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.