Jo *_*iss 29 ruby metaprogramming
我读的元编程部分编程Ruby 1.9的,我无法理解这是怎么回事内部之间class_eval/ class_exec对比instance_eval/ instance_exec.
首先,我的理解是def在self(类对象)的方法表中添加一个方法:
class A
puts self # => A
def foo; 42; end # added to the method table of self, so becomes an instance method
end
A.new.foo # => 42
Run Code Online (Sandbox Code Playgroud)
如果我们使用class_eval,我们会得到相同的行为:
A.class_eval do
puts self # => A
def bar; 42; end # same as above
end
A.new.bar # => 42
Run Code Online (Sandbox Code Playgroud)
但不知何故,instance_eval情况有所不同:
A.instance_eval do
puts self # => A
def baz; 42; end # added to the method table of an anonymous
# singleton class of self, so becomes a class method
end
puts A.baz # => 42
s = 'string'
s.instance_eval do ... end # same behavior, so now def creates an instance method
Run Code Online (Sandbox Code Playgroud)
所以我理解class_eval和之间的功能差异instance_eval.
但是class_eval和instance_eval块中的上下文对我来说看起来完全一样 - 特别是self指向同一个对象,并且local_variables它们是相同的.那么块内(内部)正在发生什么样的def行为呢?
我能阅读一些文件吗?instance_eval和class_eval的RDoc 没有帮助.查看源代码,instance_eval似乎设置了一个单例类对象而class_eval没有 - 但是这个区别在C代码之外可见,在Ruby级别上?
kru*_*.ar 34
我认为你的困惑来自于def不依赖于当前的自我这一事实,你可能会认为它是一个拥有自己规则的"当前阶级".
按照你的例子:
class A
# defs here go to A
puts self # => A
class << self
#defs here go to A's eigenclass
end
end
A.class_eval do
#defs here go to A
end
A.instance_eval do
#defs here go to A's eigenclass
end
s = "Hello World"
class << s
#defs here go to s's eigenclass
end
Run Code Online (Sandbox Code Playgroud)
这一章的部分讨论了这个问题,并且很清楚这个行为
class_eval和instance_eval都在块的持续时间内设置self.但是,它们在为方法定义设置环境的方式上有所不同.class_eval设置就好像你在类定义的主体中一样,所以方法定义将定义实例方法相反,在类上调用instance_eval就好像你在self的单例类中工作一样.因此,您定义的任何方法都将成为类方法.
我认为唯一值得添加的是你可以在任何对象中调用instance_eval,而不仅仅是类,并且行为不会改变但会产生不同的后果.
一些相关的阅读:
Ruby:instance_eval和class_eval方法定义