A parameter received by a method is a reference to the same object as the argument passed to it, e.g.:
def object_id_of_param(object)
object.object_id
end
the_object = [1, 2, 3]
the_object.object_id # => 15247020
object_id_of_param(the_object) # => 15247020
If you call an instance method of that object that modifies the object in-place from any reference to the object, regardless of scope, the single object that all variables reference is itself modified in-place, e.g.:
def modify_object(object)
object.map! { |n| n + 1 }
end
the_object = [1, 2, 3]
the_object.object_id # => 18047480
the_object # => [1, 2, 3]
modify_object(the_object)
the_object.object_id # => 18047480
the_object.inspect #=> [2, 3, 4]
If you want to do something else to that object and a method like Array#map!
is not available to do it, you can use Object@instance_variable_set
to change it (see ndn's great answer).
If you try to change it to a different class entirely, it doesn't work; the following method does not modify the original object. It does not turn it from an Array
into a Time
; it causes the new object
variable in the method to reference a new Time
object:
def fail_to_modify_object(object)
object = Time.now
end
the_object = [1, 2, 3]
the_object.object_id # => 14554660
the_object.inspect #=> [1, 2, 3]
fail_to_modify_object(the_object)
the_object.object_id # => 14554660
the_object.inspect #=> [1, 2, 3]
The example of turning an Array
object into a new Time
is contrived, but you get the idea.
Is it possible to change an object, referred to by an arbitrary number of variables, into an instance of a different class?