[英]Ruby's def and instance_eval vs. class_eval
我正在阅读Programming Ruby 1.9的Metaprogramming部分,我无法理解class_eval
/ class_exec
与instance_eval
/ instance_exec
之间的内部 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
如果我们使用class_eval
,我们会得到相同的行为:
A.class_eval do
puts self # => A
def bar; 42; end # same as above
end
A.new.bar # => 42
但不知何故,在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
所以我理解class_eval
和instance_eval
之间的功能差异。
但是class_eval
和instance_eval
块中的上下文对我来说看起来完全相同 - 特别是, self
指向同一个对象,而local_variables
是相同的。 所以,这是怎么回事块(内部)这是制作内def
作用有什么不同?
我能阅读一些文件吗? instance_eval和class_eval的RDoc没有帮助。 查看源代码, instance_eval似乎设置了一个单例类对象而class_eval没有 - 但是这个区别在C代码之外可见,在Ruby级别上?
我认为你的困惑来自于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
这一章的部分讨论了这个问题,并且很清楚这个行为
class_eval和instance_eval都在块的持续时间内设置self。 但是,它们在为方法定义设置环境的方式上有所不同。 class_eval设置就好像你在类定义的主体中一样,所以方法定义将定义实例方法相反,在类上调用instance_eval就好像你在self的单例类中工作一样。 因此,您定义的任何方法都将成为类方法。
我认为唯一值得添加的是你可以在任何对象中调用instance_eval,而不仅仅是类,并且行为不会改变但会产生不同的后果。
一些相关的阅读:
只是添加到@ krusty.ar的答案: def
和define_method
将方法添加到当前方法定义上下文 (我相信它的名称,我不确定),而不是当前的self
。
只是在模块,类或单例类体内部,这两者恰好相同。
但是,例如,在脚本体(也称为顶级)中, self
是main
对象,但当前方法定义上下文是Object
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.