Is there a way to pass objects by value and not by reference in Ruby? For Example,
class Person
attr_accessor :name
end
def get_name(obj)
obj.name = "Bob"
puts obj.name
end
jack = Person.new
jack.name = "Jack"
puts jack.name
get_name(jack)
puts jack.name
the output should be
Jack
Bob
Jack
instead of
Jack
Bob
Bob
Any help would be appreciated.
No. Ruby passes by reference, not value.
If you need to simulate passing by value, you can use Ruby's Object#clone method. In this case, you'd do something like this:
def get_name(obj)
new_object = obj.clone
new_object.name = "Bob"
puts new_object.name
end
This makes a shallow copy of an object. In other words, an object's instance variables are copied, but the objects the variables reference aren't copied. If you need to do a deep copy, you can read this Stack Overflow post. Ruby doesn't have a one-method way to perform deep copies, but that post describes how to use marshalling and unmarshalling to make a deep copy.
clone and dup work very similarly, but there are some differences. According to the docs:
Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. Copies the frozen and tainted state of obj. See also the discussion under Object#dup.
Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. dup copies the tainted state of obj. See also the discussion under Object#clone. In general, clone and dup may have different semantics in descendant classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendant object to create the new instance.
This method may have class-specific behavior. If so, that behavior will be documented under the #initialize_copy method of the class.
You can take a look at the dup and clone docs.
While my answer probably gives what the OP was looking for, it is not strictly correct, with respect to the semantics of passing by reference or value. See the other answers and comments on this page for some more discussion. You can also look at the discussion in the comments here and this post for more information.
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