I got something, ActiveRecord::Associations::AssociationProxy redefines === and defines
def method_missing(method, *args, &block)
load_target
@target.send(method, *args, &block)
end
I traced method_missing is called whenever object.assoc.class is called and delegates the call to @target, which is a true Array. That explains partially what we see, but I fail to understand why is method_missing called at all with a method inherited from Object.
It looks like Ruby doesn't even use the === operator in the case()
statement:
irb(main):005:0> class C; def ===(k); puts "called=== with
#{k.inspect}";true; end; end
=> nil
irb(main):006:0> case C.new; when String; 'string'; else; 'not'; end
=> "not"
irb(main):007:0> C.new===String
called=== with String
=> true
Maybe this question is ready to be ported over to ruby-talk.
Ah, that's it. So AssociationProxy won't ever be able to intercept the
=== call in the case/when, thus never allowing it to match the "when
Array" statement. That clears it up...