为什么Ruby定义Object#=〜?

时间:2012-12-22 13:31:55

标签: ruby

在阅读another question中的答案评论并进行一些研究后,我发现=~已定义Object,然后被String和{{覆盖1}}。 RegexpString的实现似乎假设另一个类:

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

3 个答案:

答案 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,...完全一致时,不能返回falseClass#>。请注意,nil已决定在这些情况下返回{{1}}。