2013-09-19 5 views
2

method_missing показан в Object.private_methods, а не в Object.public_methods.method_missing visibility in Ruby

Однако, когда я называю Object.method_missing :stupidmethod, я получаю

NoMethodError: undefined method `stupidmethod' for Object:Class 

Я бы ожидать, чтобы получить

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

, потому что это то, что я получаю, когда я пытаюсь вызвать другие частные методы Object «ю.ш. , например Object.chop.

Как больше доказательств, если я называю Object.method_missing без аргумента, я получаю

ArgumentError: no id given 

Таким образом, кажется, что я действительно является вызовом, что «частной» method_missing функции из-за пределы своего объекта. Вы можете это объяснить?


EDIT: Спасибо Юджину в комментариях. ruby --version говорит мне 1.8.7. Также irb --version - 0,9,5 (05/04/13). Хорошо знать, что это ведет себя так, как я ожидал в более поздних версиях.

+0

Возможно, это [сообщение] (http://www.skorks.com/2010/04/ruby-access-control-are-private-and-protected-methods-only-a-guideline/) имеет ответ – tihom

+2

С MRI 1.9.3 и 2.0.0 я действительно получаю 'NoMethodError'. Какую версию Ruby вы используете? Каков контекст вашего кода? –

+3

fwiw: Я проверил, что 1.9.3, 2.0 и rubinius возвращают ошибку 'private method method_missing'. 1.8 и jruby (в режиме 1.9) return 'undefined method stupidmethod' – Eugene

ответ

1

Это не частный метод Object, который вызывается, а метод модуля в Kernel. Вы можете проверить, какой метод вызываются с set_trace_func, как описано в 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:[email protected](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 

Как некоторые комментаторы отметили, в MRIs новее 1.8.7 этого поведение изменилось: method_missing был удален из Kernel и методы частного экземпляра от Object был перенесен на BasicObject, который является новым суперклассом.

Смежные вопросы