Method_missing behaves differently when a method is called via reflection?

Thanks Jacob. I should have thought of that; it's just like Java
reflection.

···

-----Original Message-----
From: Jacob Fugal [mailto:lukfugl@gmail.com]
Sent: Friday, November 10, 2006 4:17 PM
To: ruby-talk ML
Subject: Re: method_missing behaves differently when a method is called
via reflection?

On 11/10/06, Hartin, Brian <Brian.Hartin@pearson.com> wrote:

For certain methods, it seems to behave differently if called via
reflection. Consider the following example:

class Foo
  def method_missing(method, *args, &block)
    "#{method} called"
  end
end

f = Foo.new

f.bar('a')

-> "bar called"

f.send(:bar, 'a')

-> "bar called"

f.open('a')

-> "open called"

f.send(:open, 'a')

Errno::ENOENT: No such file or directory - a
        from (irb):8:in `initialize'
        from (irb):8

----

I know that 'open' is a Kernel method, but I would have expected
f.open('a') and f.send(:open, 'a') to behave similarly - either call

the

Kernel method or call method_missing. Does anyone know why they're
different?

All Kernel methods are private. Usually, a Kernel method is called in
procedural style (without a receiver) and since every object includes
Kernel, the private method is visible and called. But when there is an
explicit receiver ("receiver.method_name"), private methods are left
out of the lookup. So when you call f.open, the private Kernel#open is
masked and the unhandled method is passed on to method_missing.
Object#send, however, bypasses privacy restrictions so f.send(:open)
catches hold of Kernel#open and you get the error.

So, in short, it's a matter of: private w/ send vs. private w/o send

Jacob Fugal
****************************************************************************
This email may contain confidential material.
If you were not an intended recipient,
Please notify the sender and delete all copies.
We may monitor email to and from our network.
****************************************************************************