πŸ“œ ⬆️ ⬇️

Equality in Ruby

For beginner rubists, four kinds of equality checks in a language are frightening.
And this is the vaunted Ruby, which is famous for its simplicity and elegance. Let's try to figure out what's what, and why it took so many functions. For verification, we will use the following objects.

string = "some string" same_string = string copy_string = "some string" int = 7 same_int = int copy_float = 7.0 new_int = 7 class TestClass def initialize(content) @content = content end end class SubTestClass < TestClass def initialize(content) super(content) end end test_obj = TestClass.new("something") same_obj = test_obj new_obj = TestClass.new("something") sub_obj = SubTestClass.new("something") 



1. Method equal? ​​()
')
Perhaps the easiest method. It is defined in the class Object and cannot be rewritten in child classes (as it turned out, maybe, but it is not recommended !). All he does is check whether the variables point to the same object.
Checking:
 puts string.equal?(same_string) #true,  ,     puts string.equal?(copy_string) #false,    puts int.equal?(same_int) #true,   puts int.equal?(copy_float) #false 7  7.0 -   puts int.equal?(new_int) #true,    Fixnum    ,   # object_id   . ,   ,    new_int,  int puts test_obj.equal?(same_obj) #true,   puts test_obj.equal?(new_obj) #false, ,   puts test_obj.equal?(sub_obj) #false,   ,    

Well here everything is clear, moving to the next method.

2. Method eql? ()

Also defined in the Object class. It works the same way as equal? ​​(), But is overridden in subclasses (in particular, all Numeric and String) - returns true if objects have the same values, however, they are also verified that they belong to the same class. Used by the Hash class.

 puts string.eql?(same_string) #true, ,       puts string.eql?(copy_string) #true, -  puts int.eql?(same_int) #true,   equal? ,  eql?   puts int.eql?(copy_float) #false, ,   puts int.eql?(new_int) #true,  ,  ,   puts test_obj.eql?(same_obj) #true, ,   puts test_obj.eql?(new_obj) #false, !,  eql?     Object,  #  equal? puts test_obj.eql?(sub_obj) #false, ,  ,   


3. ==
At the class level, Object does the same thing as equal? ​​(Again!), That is, it checks whether variables point to one object, but the behavior in subclasses (in particular, numeric and strings) is rewritten differently - only values ​​are checked, and ownership is not required. class (for numeric), what is the difference with eql? ..

 puts string == (same_string) #true,   puts string == (copy_string) #true,   puts int == (same_int) #true,     puts int == (copy_float) #true, - ,    puts int == (new_int) #true,   #!     ==  ,     #Object,      equal? puts test_obj == (same_obj) #true puts test_obj == (new_obj) #false puts test_obj == (sub_obj) #false 


4. ===
The results for === are exactly the same as for == (with one β€œbut” for strings and regular expressions). The most frequent use of triple equals is in the case component when comparing, as you might have guessed, strings and regular expressions.
The only example I will give here is:

 puts /p.*cock/ == 'peacock' #false,   ==    , puts /p.*cock/ === 'peacock' #true,    === 


This is the only small difference.

Conclusion:

Most often we use only two methods - equal? ​​() And ==. The main thing is to remember that equal? ​​() Is always (!) And I repeat, always, it only checks if the variables point to one object.

== does the same thing. However, at a purely intuitive level, it is clear that the double is equal for simple data types like Fixnum, String, Float - those that we use most often, should only check the equality of values. That is why == was rewritten for them that way. And when developing your classes, it's better to override == to check only the content.

eql? used by the Hash class, but there is no special need for ordinary programmers. The only thing is, if you want to extend the functionality == for simple types (for which this function is redefined) also by checking for belonging to one class, then you can use eql?

As for ===, it is rarely used to use it at all, since this function was implemented mostly for the case control element. However, if there is a need to compare a regular expression and a string (with something other than = ~, but why?), Then the triple is useful here as well.

Source: https://habr.com/ru/post/124113/


All Articles