Salomanuel Salomanuel - 1 month ago 7
Ruby Question

why return change variables while inside a class

I cannot understand this ruby behavior, the code explains better what I mean:

class DoNotUnderstand
def initialize
@tiny_array = [3,4]
test
end

def messing(ary)
return [ary[0]+=700, ary[1]+=999]
end

def test
puts @tiny_array.join(",") # before => 3,4
messing(@tiny_array)
puts @tiny_array.join(",") # after => 703,1003
end
end

question = DoNotUnderstand.new


@tiny_array
was
[3,4]
and became
[703,1003]


if I don't use a class, that happens:

@tiny = [1,2]
def messing(ary)
return [ary[0]+693,ary[1]+999]
end

puts @tiny.join(",") # before => 1,2
messing(@tiny)
puts @tiny.join(",") # after => 1,2


the array simply remains
[1,2]


why?

Answer

The class is a red herring, and completely irrelevant to the issue.

In the first case, where the array was modified, you defined messing as:

def messing(ary)
  return [ary[0]+=700, ary[1]+=999]
end

Whereas in the second case, where the array was not modified, you defined messing as:

def messing(ary)
  return [ary[0]+693,ary[1]+999]
end

In one case you used +=, and in the other, you used merely +.

ary[0] += 700 is exactly equivalent to ary[0] = ary[0] + 700. In other words you are changing the value stored in the 0th index of ary.

In the second case you merely add to the values stored in the array and return the result, but in the first case you not only return the result, you also store it back in the array.

For an explanation of why modifying ary modifies @tiny_array, see this answer to the question Is Ruby pass by reference or by value?.