meg*_*gas 2 ruby metaprogramming
这段代码创建方法作为私有方法,为什么?
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
Run Code Online (Sandbox Code Playgroud)
平台:ruby 1.9.3p125,经过测试 pry
在任何模块之外定义的方法(所谓的全局方法)实际上被定义为私有实例方法Object.这样,可以随处调用(因为所有内容都是从中继承Object),并且只能在没有显式接收器的情况下调用它们.
这包括类似方法require,load,puts,print,p,gets,和eval.(注意:大多数实际上已定义Kernel并混合使用,Object但效果和目标是相同的.)
在您的情况下,您正在定义任何模块之外的方法:您的a字符串中没有提及模块.您呼叫的事实eval在A.class是完全不相干的.就像我上面说的那样:eval是Object为了方便起见而定义的全局方法(因此可以在任何地方调用它).您A.class.send(:eval)只是一种非常复杂的调用全局私有eval方法的方法.它并没有以某种方式神奇地将evaluated字符串的上下文设置为A.class.
你可以做,42.send(:eval)而结果仍然是相同的,就像puts('Hello')和42.send(:puts, 'Hello')完全一样,因为他们最终调用完全相同的方法.
顺便说一下:即使它确实如此,它仍然不会做你想要的.A.class只是Class(在class的任何类总是 Class),所以如果没有工作,你期望的那样,该方法将被定义Class,而不是在A.