在阅读another question中的答案评论并进行一些研究后,我发现=~
已定义Object
,然后被String
和{{覆盖1}}。 Regexp
和String
的实现似乎假设另一个类:
Regexp
虽然为"123" =~ "123" # => TypeError: type mismatch: String given
/123/ =~ /123/ # => TypeError: can't convert Regexp to String
定义了=~
,但Object
不是:
+
为什么定义了Object.new =~ 1 # => nil
Object.new + 1 # => undefined method `+' for #<Object:0x556d38>
,而不是将Object#=~
限制为=~
和String
?
答案 0 :(得分:2)
好吧,我想在字符串=~
documentation中确实很好地回答了:
匹配 - 如果obj是
Regexp
,请将其用作与str匹配的模式,并且 返回匹配开始的位置,如果没有匹配则返回nil
。否则,调用
obj.=~
,将str
作为参数传递。默认=~
在Object中返回nil
。
关键是,您可以编写自己的对象=~
实现 - 它将在String =~ Not Regexp
语句中使用。
答案 1 :(得分:2)
因为它允许在匹配表达式中使用任何对象:
Object.new =~ /abc/
=> nil
我认为这与Object.new
与正则表达式/abc/
不匹配的方式有意义,如果左参数不是String
对象,代码会爆炸。所以它通常简化了代码,因为你可以在=~
运算符的左侧有任何对象。
答案 2 :(得分:2)
根据您的评论,您的实际问题是为=~
定义了Object
而+
未定义的原因。
原因是Object#=~
可以为随机对象返回nil
(因为它们不匹配),但Object#+
无法返回有意义的结果。
它不一定非常有用,但不能说是假的(你必须展示一个匹配来证明nil
结果是矛盾的)。参见vacuous truth的数学概念。另一方面,Object.new + 1
的任何结果都可能导致矛盾。
这与<=>
类似,nil
可以返回Object
(因此也在<
上定义)>
,true
,...完全一致时,不能返回false
或Class#>
。请注意,nil
已决定在这些情况下返回{{1}}。