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
?
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.
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With