-1

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?

Salomanuel
  • 897
  • 10
  • 22

2 Answers2

6

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?.

Community
  • 1
  • 1
philomory
  • 1,709
  • 12
  • 13
2

You're second code example (the one from outside the class) is missing the two characters in the first that make it work the way it does. In the first example, the += operator is used, modifying the array in place:

return [ary[0]+=700, ary[1]+=999]

In your second example, the + operator is used, leaving the array as is:

return [ary[0]+693,ary[1]+999]

If you change it use the += operator, it works the same way as the first code snippet.

Linuxios
  • 34,849
  • 13
  • 91
  • 116