Last week, I wanted to answer the question here /qaru.site / ... , but after running some tests in irb, I found an interesting thing.
class X def ==(other) p "X#==" super end end data = [ 1 ] data.include?(X.new)
I expect Array#include? will call Fixnum#== for each element of the array. Thus, X#== never called, and the debug message is never printed.
But in fact, in my ruby versions (REE 1.8.7, MRI 1.8.7, 1.9.2, and 1.9.3) it displays the debug message X#== .
If I do this on true or false or nil or even Object.new , it never prints the X#== message.
But if I redefine Fixnum#== as follows:
class Fixnum def ==(other) p "Fixnum#==" super end end
What actually causes the original implementation after printing the debug message, it prints Fixnum#== and X#== will never be printed, as I expected initially.
Update
This gets even crazier when I switch the haystack with a needle:
data = [ X.new ] data.include?(1)
It outputs X#== , although he used to call the #== method on the needle.
Can anyone indicate what is the reason for this? Or just an optimization problem?