This snippet of code creates method as a private method, why?
a = %q{def hello() "Hello there!" end}
class A; end
A.class.send(:eval, a)
A.new.hello #=> NoMethodError: private method `hello' called for A
Platform: ruby 1.9.3p125, tested in pry
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
Methods which are defined outside of any module (so called global methods) are actually defined as private instance methods of
Object. That way, the can be called everywhere (since everything inherits fromObject), and they can only be called without an explicit receiver.This includes methods like
require,load,puts,print,p,gets, andeval. (Note: most of those are actually defined inKerneland mixed intoObjectbut the effect and the objective is the same.)In your case, you are defining a method outside of any module: there is no mention of a module in your
astring. The fact that you are callingevalonA.classis completely irrelevant. Like I said above:evalis a global method defined onObjectfor convenience reasons (so that it may be called everywhere). YourA.class.send(:eval)is just a very convoluted way of calling the global privateevalmethod. It does not somehow magically set the context of theevaluated string toA.class.You could do
42.send(:eval)instead and the result would still be the same, just likeputs('Hello')and42.send(:puts, 'Hello')are exactly the same, because they end up calling the exact same method.And by the way: even if it did, it still wouldn’t do what you want.
A.classis justClass(theclassof any class is alwaysClass), so if it did work as you expect, the method would be defined inClass, not inA.