先週、stackoverflow.comで質問に答えたかったのですが、 irbでいくつかのテストを実行した後、興味深いことがわかりました。
class X
def ==(other)
p "X#=="
super
end
end
data = [ 1 ]
data.include?(X.new)
ここでは、配列内のすべてのアイテムArray#include?が呼び出されることを期待しています。Fixnum#==したがって、X#==が呼び出されることはなく、デバッグ メッセージが出力されることもありません。
しかし、実際には私のルビー バージョン (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#==呼び出したのにプリントアウトしてしまいます。#==
その背後にある理由を誰か指摘できますか?それとも単に最適化の問題ですか?