Frage

method_missing shows up in Object.private_methods, not in Object.public_methods.

However, when I call Object.method_missing :stupidmethod, I get

NoMethodError: undefined method `stupidmethod' for Object:Class

I would expect to get

NoMethodError: private method `method_missing' called for Object:Class

because that's what I get when I try to invoke Object's other private methods, e.g. Object.chop.

As more evidence, if I call Object.method_missing without an argument, I get

ArgumentError: no id given

So it seems like I really am invoking that "private" method_missing function from outside of its object. Can you explain this?


EDIT: Thank you to Eugene in the comments. ruby --version tells me 1.8.7. Also, irb --version is 0.9.5(05/04/13). Good to know that this behaves as I'd expect in the later versions.

War es hilfreich?

Lösung

It is not the private method of Object that is called but the module method in Kernel. You can check which method is called with set_trace_func as described in the answer to a similar question:

irb(main):001:1> set_trace_func proc { |event, file, line, id, binding, classname|   printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname if id.to_s == 'method_missing' }
=> #<Proc:0x0423d278@(irb):1>
irb(main):002:0> Object.method_missing :test
c-call (irb):4  method_missing   Kernel
c-return (irb):4  method_missing   Kernel
NoMethodError: undefined method `test' for Object:Class
    from (irb):4
    from :0

As some commenters pointed out in MRIs newer than 1.8.7 this behaviour has changed: method_missing has been removed from Kernel and the private instance method from Object was moved to BasicObject which is the new superclass.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top