David,
Thank you for your reply. It wasn’t what I was hoping for, but I still
appreciate it.
What I meant to ask is when can calling foo.bar() result in a different
method call from foo.method(:bar).call() in the case where there really
is a method called ‘bar’. Kudos for pointing out that the error message
is different when ‘bar’ doesn’t exist, but that wasn’t what I was
looking for. =)
And similarly, why could binding an object to a method fail with a type
error, even when the object’s class method is reporting that it is of
the correct class.
Yes, it’s possible that the object is overriding both “class” and
“method”, but I really don’t think so. And even if you did, it doesn’t
explain how “bind” figures out that it’s not really an Array.
I agree that one shouldn’t be so worried about what class an object
reports itself as. But this is the very reason why I don’t think the
rails implementation would bother overriding “class” and “method”.
I’d love to know what mechanism they used to achieve this magic. If it
was me, I would have probably made a sub-class of Array. If not that,
then I would have inserted my own find_all with an “extend” call. But
that would also show up when you called method(:find_all). So they’re
doing something else. If push comes to shove, I can start pouring
through the rails code… but ugh…
I’m sorry if I sounded bitter. I’m not really. These things happen.
There’s a reason why this rails “find_all” method is marked as
deprecated. When I was searching for answers I found all kinds of
confusion it generated (many on this forum), including a patch that was
submitted a year ago that would have tried to eliminate some of the
confusion:
http://dev.rubyonrails.org/ticket/2898
But what I’m more interested in is what mechanism in the Ruby language
is being used to get the alternate find_all behaviour.
Perhaps this would have been a better post for the Rails group, but it
seemed more like a Ruby language question to me.
So my real question is what really happens when the Ruby interpreter
see’s foo.bar ???
I’m guessing the answer in the FAQ about how Ruby chooses what method to
invoke is not really precise. And I don’t think the answer is in the
common Ruby books.
Thanks again!
Chad
David A. Black wrote:
Hi –
On 3/14/07, Chad L. [email protected] wrote:
Ruby pop quiz. How can it be that:
foo.bar()
is different from:
foo.method(:bar).call()
Here’s one time:
irb(main):001:0> class C; def method_missing(m); puts “caught!”; end;
end
=> nil
irb(main):002:0> C.new.x
caught!
=> nil
irb(main):003:0> C.new.method(:x).call
NameError: undefined method x' for class
C’
Is it possible to override the “method” method?
Can you also override the “class” method?
Sure. I don’t think there are any non-overridable methods in Ruby.
It’s all open.
shows the ancestor classes and modules of ClassName.
If this is true, then I only need to check three places to see what
method will be called. Is there a way for me to look the same way Ruby
does?
You can check the various classes and modules with instance_methods
and other similar methods.
For those that are curious… the real life example that raised this
question for me was in rails. When you have a Model with a has_many
relationship it creates an Array-like object that looks very much like
an Array, but behaves as described above (with a secret undocumented
deprecated find_all) method.
You sound bitter Keep in mind that class isn’t really very
important in Ruby. Generally you’re more concerned with what a given
object actually does. So while these AR collections report themselves
as Arrays, the main thing is their behavior, which is kind of a
souped-up Array behavior.
David