Reputation: 1068
In Java I can do:
public boolean equals(Object other) {
return this.aPrivateVariable == ((MyClass)other).aPrivateVariable;
}
This allows me to define equality without breaking the encapsulation of my class. How can I do the same in Ruby?
Thanks.
Upvotes: 5
Views: 519
Reputation: 89093
As others have pointed out, you need to redefine #==
in your class. One gotcha, though, is hash tables. If you want two different instances of your class with o1 == o2 #=> true
to hash to the same value in a hash table, then you need to redefine #hash
and #eql?
so the hash table knows they represent the same value.
class Foo
def initialize(x,y,z)
@x,@y,@z = x,y,z
end
def ==(other)
@y == other.instance_eval { @y }
end
end
o1 = Foo.new(0, :frog, 2)
o2 = Foo.new(1, :frog, 3)
o1 == o2 #=> true
h1 = Hash.new
h1[o1] = :jump
h1[o2] #=> nil
class Foo
def hash
@y.hash
end
def eql?(other)
self == other
end
end
h2 = Hash.new
h2[o1] = :jump_again
h2[o2] #=> :jump_again
Upvotes: 0
Reputation: 370367
In ruby instance variables as well as private methods are accessible only to the object itself, not to any other object no matter their class. Protected methods are available to the object itself and other objects of the same class.
So to do what you want you can define a protected getter-method for your variable.
Edit: An example:
class Foo
protected
attr_accessor :my_variable # Allows other objects of same class
# to get and set the variable. If you
# only want to allow getting, change
# "accessor" to "reader"
public
def ==(other)
self.my_variable == other.my_variable
end
end
Upvotes: 7
Reputation:
Just do the comparison without the cast which is not necessary in Ruby.
class C1
attr_accessor :property
def == other
property == other.property
end
end
class C2
attr_accessor :property
def == other
property == other.property
end
end
c1 = C1.new
c1.property = :foo
c2 = C2.new
c2.property = :bar
p c1 == c2 # => false
c1.property = :bar
p c1 == c2 # => true
Edit: Changed equals?
to ==
.
Upvotes: -1