上周我想在stackoverflow.com上回答一个问题,但是在irb中运行了一些测试后,我发现了一件有趣的事情。
class X
def ==(other)
p "X#=="
super
end
end
data = [ 1 ]
data.include?(X.new)
我希望这里Array#include?
会调用Fixnum#==
数组中的每个项目。所以X#==
永远不会调用 is 并且永远不会打印调试消息。
但实际上在我的 ruby 版本(REE 1.8.7、MRI 1.8.7、1.9.2 和 1.9.3)中,它会打印出X#==
调试消息。
如果我这样做true
或false
或nil
什至Object.new
它永远不会打印出X#==
消息。
但如果我重新定义Fixnum#==
这样的:
class Fixnum
def ==(other)
p "Fixnum#=="
super
end
end
在打印调试消息后实际上调用了原始实现,它打印出来Fixnum#==
并且X#==
永远不会像我最初预期的那样打印出来。
更新
当我用针切换干草堆时,它变得更加疯狂:
data = [ X.new ]
data.include?(1)
X#==
即使它#==
之前调用了针上的方法,它也会打印出来。
有人能指出这背后的原因吗?或者只是一个优化问题?