对String子类的重写=〜方法会产生不一致

时间:2014-02-28 18:27:25

标签: ruby method-overriding

我覆盖=~的子类的String方法:

class MyString < String
  def =~(obj)
    "Overridden method."
  end
end
s = MyString.new "abc"

在某些情况下,正确调用了重写方法:

r = /abc/
s =~ r             # => "Overridden method."
s.send(:=~, r)     # => "Overridden method."
s.send(:=~, /abc/) # => "Overridden method."

而在其他情况下,它被绕过,而String#=~则被调用:

s =~ /abc/         # => 0
s =~ (/abc/)       # => 0

我可以在Ruby 1.8.7,2.1.0上重现这些结果。有人知道为什么会这样吗?这是一个错误吗?

1 个答案:

答案 0 :(得分:1)

String#=~方法的源代码中,Ruby处理特殊情况,其中参数是解析器使用的内置 Regexp类型,即我们写s =~ /abc/时的情况。

可以将rb_reg_match方法视为Regexp#=~方法。

因此,如果你真的想要这种行为,你可以修补Regexp类以接受{~1}}的{​​{1}}对象,但这可能非常非常容易出错。

另一种方法是构图。您可以包含Forwardable模块,也可以使用普通的MyString。这是一个例子:

method_missing