1.4.1.8. fejezet, Argumentum átadás és visszatérési értékek

Mint korábban láthattuk, az utolsó kifejezés értéke lesz egy metódus visszatérési értéke.

def method3
  "hello" # returns “hello”
end

Több visszatérési érték lehetséges, az alábbi pl. tömböt ad vissza.

def ret_things
  greeting = "Hello world"
  a = 1
  b = 2.0
  return a, b, 3, "four", greeting, 6 * 10
end

Ez pedig egy hash táblát

def ret_hash
  return {'a'=>'hello', 'b'=>'goodbye', 'c'=>'fare thee well'} 
end

Alapértelmezett éterérték adható az argumentumoknak.

def aMethod( a=10, b=20 )
  return a, b
end
 
p( aMethod ) #=> displays: [10, 20]
p( aMethod( 1 )) #=> displays: [1, 20]
p( aMethod( 1, 2 )) #=> displays: [1, 2]

Határozatlan számú argumentumszám, határozatlan számú visszatérési értéket is jelent, mint korábban volt szó erről:

def aMethod( a=10, b=20, c=100, *d ) 
  return a, b, c, d
end
 
p( aMethod( 1,2,3,4,6 ) ) #=> displays: [1, 2, 3, [4, 6]]

Az OOP "egy út befelé, egy út kifelé" szabálya szerint egy metódus nem változtathatja meg a bemenő argumentum értékeit, csak visszatérési értékben észlelhető a változás. Ezt a Ruby is - mint sok más OOP nyelv, igyekszik betartani.

def change( x ) 
  x += 1 
  return x 
end
 
x=10
y=change(x)
puts(x,y) => # 10 11

Vannak azonban kivételek. Korábban említettük a ! operátort és a << operátort. Mindkettő megváltoztatja a bal oldali objektumot.

def nothidden( aStr, anotherStr )
  anotherStr = aStr << " " << anotherStr
  return aStr << anotherStr.reverse
end
 
str1 = "dlrow"
str2 = "olleh"
str3 = nothidden(str1, str2)
puts( str1 ) # input arg: changed (“dlrow ollehhello world”)
puts( str2 ) # unchanged
puts( str3 ) # returned value(“dlrow ollehhello world”)
def nothidden( aStr, anotherStr )
  anotherStr = aStr << " " << anotherStr
  return aStr << anotherStr.reverse!
end
 
str1 = "dlrow"
str2 = "olleh"
str3 = nothidden(str1, str2)
puts( str1 ) # hello worldhello world
puts( str2 ) # unchanged
puts( str3 ) # returned value(“hello worldhello world”)

String esetében a + jellel történő hozzáfűzéskor új objektum keletkezik.

def hidden( aStr, anotherStr ) 
  anotherStr = aStr + " " + anotherStr 
  return aStr + anotherStr.reverse
end
 
str1 = "dlrow" 
str2 = "olleh" 
str3 = hidden(str1, str2) # str3 receives returned value
puts( str1 ) # input args: original values unchanged
puts( str2 )
puts( str3 ) # returned value ( “dlrowhello world” )

Ha egy egész szám (Fixnum) változó értékét változatlanul adjuk vissza, akkor a két objektum azonos lesz. Korábban említettük, hogy minden egész szám objektum_id tulajdonsága előre meghatározott. Ezért igaz az x==z vagy x.eual?(z)

def nothing(x)
  puts("oid1:"+x.object_id.to_s)
  return x
end
y=nothing(10)
puts("oid2:"+y.object_id.to_s)
x=10
z=x
puts(x.equal?(z)) #=> true
puts(y===z) #=> true

Párhuzamos értékadás

Több változónak adhatunk értéket, több féle képen:

s1, s2, s3 = "Hickory", "Dickory", "Dock"
i1 = 1
i2 = 2
 
i1, i2 = i2, i1 # értékcsere segédváltozó nélkül
x, y, z = returnArray( "Fred", "Bert", "Mary" )
x, y, z, extravar = returnArray( "Fred", "Bert", "Mary" ) # extravar = nil
s1, s2, s3 = ["Ding", "Dong", "Bell"]

A tört számok egyedi azonosítót kapnak, akár csak a String objektumok. De nézzük csak az alábbi értékadást. Egyezőség vizsgálatnál igaz értéket ad.

num = 11.5
num2 = 11.5 # num and num 2 are not equal
puts( "num.equal?(num2) #{num.equal?(num2)}" )
num = num2 # but now they are equal
puts( "num.equal?(num2) #{num.equal?(num2)}" )

Ez a referencia hivatkozás. Az alábbi két összehasonlítás is a referencia hivatkozást mutatja be.

ob1 = Object.new
ob2 = Object.new
puts( ob1==ob2 ) #<= false

Mivel String objektumnál felülírták az egyenlőség vizsgálatát, ezért a tartalom alapján egyenlőnek látszik, referencia szerint különböző.

s1 = "hello"
s2 = "hello"
puts( s1==s2 ) #<= true
puts( s1.equal?(s2) ) #<= false