Coming from a c++ background I'm curious about object assignment in Ruby. What considerations (if any) should be made for the following object assignments:
class MyClass
attr_accessor :a, :b
def initialize(a, b)
@a = a
@b = b
end
def some_method
puts "#{self.a} #{self.b}"
end
end
m = MyClass.new("first", "last")
n = MyClass.new("pizza", "hello")
q = n
q.some_method
If you're familiar with C++, then you might want to consider every variable in Ruby, instance or otherwise, as a reference to another object. Since everything in Ruby is an object, even nil
, which is of type NilClass, this holds true under every circumstance.
To determine which object you're referencing, you can use the object_id
method to differentiate. That's similar to converting to a pointer using &
in C++.
Consider this:
a = "foo"
b = a
a.object_id == b.object_id
# => true
Since a
is a reference to that string, and b
is a copy of a
, then they are actually different references to the same object.
This is important because operations that modify an object affect all references to that equally:
a << "bar"
# => "foobar"
b
# => "foobar"
However, operations that create a new object will not modify all copies:
a += "baz"
# => "foobarbaz"
b
# => "foobar"
Many methods in Ruby are identified by a !
to distinguish in-place versus new-copy versions, but this is not always the case, so you have to be familiar with each method in order to be sure.
Generally an assignment will replace an old reference with a new one, so as a rule of thumb, =
will replace old references. This applies to +=
, -=
, ||=
, &&=
and so on.
Edit: Updated based on Phrogz's comment about using ObjectSpace._id2ref(object_id)
to convert an object identifier into an object.
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