This blog is part of our Ruby 2.4 series.
In Ruby, Object#equal? method is used to compare two objects by their identity, that is, the two objects are exactly the same or not. Ruby also has Object#eql? method which returns true if two objects have the same value.
For example:
1 2str1 = "Sample string" 3str2 = str1.dup 4 5str1.eql?(str2) #=> true 6 7str1.equal?(str2) #=> false 8
We can see that object ids of the objects are not same.
1 2str1.object_id #=> 70334175057920 3 4str2.object_id #=> 70334195702480 5
In ruby, Set does not allow duplicate items in its collection. To determine if two items are equal or not in a Set ruby uses Object#eql? and not Object#equal?.
So if we want to add two different objects with the same values in a set, that would not have been possible prior to Ruby 2.4 .
Ruby 2.3
1 2require 'set' 3 4set = Set.new #=> #<Set: {}> 5 6str1 = "Sample string" #=> "Sample string" 7str2 = str1.dup #=> "Sample string" 8 9set.add(str1) #=> #<Set: {"Sample string"}> 10set.add(str2) #=> #<Set: {"Sample string"}> 11
But with the new Set#compare_by_identity method introduced in Ruby 2.4, sets can now compare its values using Object#equal? and check for the exact same objects.
Ruby 2.4
1 2require 'set' 3 4set = Set.new.compare_by_identity #=> #<Set: {}> 5 6str1 = "Sample string" #=> "Sample string" 7str2 = str1.dup #=> "Sample string" 8 9set.add(str1) #=> #<Set: {"Sample string"}> 10set.add(str2) #=> #<Set: {"Sample string", "Sample string"}> 11
Set#compare_by_identity?
Ruby 2.4 also provides the compare_by_identity? method to know if the set will compare its elements by their identity.
1 2require 'set' 3 4set1= Set.new #=> #<Set: {}> 5set2= Set.new.compare_by_identity #=> #<Set: {}> 6 7set1.compare_by_identity? #=> false 8 9set2.compare_by_identity? #=> true 10