0

So see the below code:

   s1 = "a"
=> "a"
   s1.class
=> String
   s1.class == String
=> true
   s1.class === String
=> false
   String == String
=> true
   String === String
=> false
   String === s1
=> true
   String == s1
=> false
   s1 == String
=> false
   s1 === String
=> false

my question is ->

  1. why String == String evaluates to true but String === String does not?

Is it because in fact those are different objects and are stored in different parts of memory? If yes then why would we initialize many Class objects of String? (shouldn't those be kind of a singleton?)

String inherits from Object and has Comparable module included. From Object String gets the .=== (https://ruby-doc.org/core-2.5.1/Object.html#method-i-3D-3D-3D)

and from Comparable it gets the .== (https://ruby-doc.org/core-2.4.0/Comparable.html#method-i-3D-3D)

From reading the definitions I see that the .=== is typically the same as .== but that's not the case with String. I don't know why though.

  1. Why s1 === String is false but String === s1 is true?

I assume it's because the .=== implementation on "a" object of a String is not the same that .=== implementation on the String class, but how does the .=== (and maybe why does it work in this way) on String work (how does it know it should compare the class of the object and not the value/place in memory)?

beniutek
  • 1,672
  • 15
  • 32
  • The same thing happens in `case`, `when String` will not match, I assume `case` uses `===`. – Kris Mar 08 '19 at 11:34
  • The difference between those two operator is clearly explained [here](https://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and). – Tashi Dendup Mar 08 '19 at 11:44
  • I agree, this question is explained in the duplicate pointed by @Kris – beniutek Mar 08 '19 at 12:39

1 Answers1

1

You are right == and === are different methods on the String class and an instance of String. Have a look at the different documentation for

Why String == String evaluates to true but String === String does not?

As you can see in the docs Module.== basically means if both sides are the same Object. Is the String class the same as the String class? Yes. But Module.=== returns true if the right side is an instance of the class on the left. Id String an instance of String? No.

Why s1 === String is false but String === s1 is true?

s1 === String calls === on an instance of string. This method returns true when both sides are the same object. Are an instance of String and the class Sting the same object? No. But String === s1 has – as already explained before the meaning of is_a?: Is an instance of String an instance of String? Yes.

spickermann
  • 100,941
  • 9
  • 101
  • 131
  • `.===` returns true is if the right side is the INSTANCE of that class. I've missed that somehow in the docs. thanks! – beniutek Mar 08 '19 at 12:36
  • It may be worth pointing out that `===` is also called the Case Equality as stated in the [`Object#===`](http://ruby-doc.org/core-2.6.1/Object.html#method-i-3D-3D-3D) documentation. This operator is called when you provide it as `when` argument. `case 'Hello World!'; when /ello/ then true; end #=> true` or `case 15; when 1..20 then true; end #=> true` – 3limin4t0r Mar 08 '19 at 12:52
  • [`Enumerable#grep`](http://ruby-doc.org/core-2.6.1/Enumerable.html#method-i-grep) also uses this operator. `[5, 25, 83, nil, 'hey'].grep(5..30) #=> [5, 25]` or `[5, 25, 83, nil, 'hey'].grep(String) #=> ['hey']` – 3limin4t0r Mar 08 '19 at 12:57