For a simple struct-like class:
class Tiger attr_accessor :name, :num_stripes end
what is the correct way to implement equality correctly, to ensure that ==
, ===
, eql?
, etc work, and so that instances of the class play nicely in sets, hashes, etc.
EDIT
Also, what's a nice way to implement equality when you want to compare based on state that's not exposed outside the class? For example:
class Lady attr_accessor :name def initialize(age) @age = age end end
here I'd like my equality method to take @age into account, but the Lady doesn't expose her age to clients. Would I have to use instance_variable_get in this situation?
Equality operators: == and != The == operator, also known as equality or double equal, will return true if both objects are equal and false if they are not. The != operator, also known as inequality, is the opposite of ==. It will return true if both objects are not equal and false if they are equal.
== Checks if the value of two operands are equal or not, if yes then condition becomes true. (a == b) is not true. !=
Two strings or boolean values, are equal if they both have the same length and value. In Ruby, we can use the double equality sign == to check if two strings are equal or not. If they both have the same length and content, a boolean value True is returned. Otherwise, a Boolean value False is returned.
To simplify comparison operators for objects with more than one state variable, create a method that returns all of the object's state as an array. Then just compare the two states:
class Thing def initialize(a, b, c) @a = a @b = b @c = c end def ==(o) o.class == self.class && o.state == state end protected def state [@a, @b, @c] end end p Thing.new(1, 2, 3) == Thing.new(1, 2, 3) # => true p Thing.new(1, 2, 3) == Thing.new(1, 2, 4) # => false
Also, if you want instances of your class to be usable as a hash key, then add:
alias_method :eql?, :== def hash state.hash end
These need to be public.
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