class Temp1
def add(s)
match = 'test'
self.class.class_eval do
define_method(s) do
puts match
end
end
#match ='haha'
end
end
正如我想的那样,"match"是一个局部变量,所以我不明白它如何从另一个方法中看到它,而且如果取消注释 #match ='haha',方法会以某种方式打印"haha"。有人可以解释一下吗?
另外,我在这里看不到使用 class_eval 或 instance_eval 之间的区别,似乎它做同样的事情。
而且,最后但并非最不重要的一点是,我可以在这里使用 define_method 创建类方法吗?所以我可以称它为Temp1.something而不是Temp1.new.something?
因为块(做...end)是闭包,可以访问其周围范围。
你用class_eval
使用了块,所以它可以访问周围的环境,这是方法的范围add
。现在您将另一个块与 define_method
一起使用,该块也可以通过带有class_eval
的块访问方法add
的范围。match
局部变量已在方法 add
的作用域内创建。因此,块可以访问变量。
而且,最后但并非最不重要的一点是,我可以使用define_method在这里创建类方法吗?
不,你不能。define_method
在接收器中定义实例方法。self.class
是Temp1
.现在在Temp1.class_eval do..end
下,你正在定义类Temp1
的实例方法,方法define_method
。define_method
是所有类的私有类方法,其中存在Object
类的祖先链。
class C;end
C.private_methods.grep(/define_/)
# => [:define_method]
另外,我在这里看不到使用 class_eval 或 instance_eval 之间的区别,似乎它做同样的事情。
好!让我为您解释一下。你在这里看不到区别,因为Teamp1
是一个Class
,也是一个Class
的实例。在调用class_eval
和instance_eval
中,self
被设置为Teamp1
,按照它们各自的定义。
class C
def self.bar;11;end
def baz;12;end
end
C.is_a? Class # => true
C.instance_of? Class # => true
C.class_eval{ bar } # => 11
C.instance_eval{ bar } # => 11
希望这有帮助!