After reading a comment to an answer in another question and doing a little research, I see that =~ is defined on Object and then overridden by String and Regexp. The implementations for String and Regexp appear to assume the other class:
"123" =~ "123" # => TypeError: type mismatch: String given
/123/ =~ /123/ # => TypeError: can't convert Regexp to String
Although =~ is defined for Object, + is not:
Object.new =~ 1 # => nil
Object.new + 1 # => undefined method `+' for #<Object:0x556d38>
Why has Object#=~ been defined, rather than restricting =~ to to String and Regexp?
Because it allows any object to be used in a match expression:
I guess this makes sense in the way that
Object.newdoes not match the regexp/abc/and the code would blow up if the left argument wasn’t aStringobject. So it generally simplifies the code because you can have any object on the left side of the=~operator.