Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the diference between these two pieces of code?

This prints 1:

def sum(i)
  i=i+[2]
end

$x=[1]
sum($x)
print $x

This prints 12:

def sum(i)
  i.push(2)
end

$x=[1]
sum($x)
print $x

The latter is modifying the global variable $x. Why is it modified in the second example and not in the first one? Will this will happen with any method (not only push) of the class Array?

like image 409
jorar91 Avatar asked Mar 04 '14 08:03

jorar91


3 Answers

Variable scope is irrelevant here.

In the first code, you are only assigning to a variable i using the assignment operator =, whereas in the second code, you are modifying $x (also referred to as i) using a destructive method push. Assignment never modifies any object. It just provides a name to refer to an object. Methods are either destructive or non-destructive. Destructive methods like Array#push, String#concat modify the receiver object. Non-destructive methods like Array#+, String#+ do not modify the receiver object, but create a new object and return that, or return an already existing object.

Answer to your comment

Whether or not you can modify the receiver depends on the class of the receiver object. For arrays, hashes, and strings, etc., which are said to be mutable, it is possible to modify the receiver. For numerals, etc, which are said to be immutable, it is impossible to do that.

like image 65
sawa Avatar answered Nov 17 '22 09:11

sawa


In the first snippet, you assign new local variable to hold result of $x + [2] operation which is returned, but it doesn't change $x (because + method doesn't modify receiver object). In your second snipped, you use Array#push method, which modifies an object (in this case, object assigned to $x global var and passed as i into your sum method) on which it's called.

like image 35
Marek Lipka Avatar answered Nov 17 '22 08:11

Marek Lipka


i.push(2) appends 2 to the array pointed by i. Since this is the same array pointed by $x, $x gets 2 appended to it as well.

i=i+[2] creates a new array and set i to it - and now this is a different array than the one pointed by $x.

like image 29
Idan Arye Avatar answered Nov 17 '22 09:11

Idan Arye