class Foo
include Module.new { class_eval "def lab; puts 'm' end" }
def lab
super
puts 'c'
end
end
Foo.new.lab #=> m c
Run Code Online (Sandbox Code Playgroud)
================================================== ======================
class Foo
include Module.new { instance_eval "def lab; puts 'm' end" }
def lab
super
puts 'c'
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,我将class_eval更改为instance_eval
Foo.new.lab rescue nil#=> no super class method lab
Foo.lab #=> undefined method lab for Foo class
Run Code Online (Sandbox Code Playgroud)
所以似乎包含模块既没有定义实例方法也没有定义类方法.
有什么解释在这里发生了什么?
此代码在mac上的ruby 1.8.7上进行了测试.
mik*_*kej 10
首先,想一想是什么include.它使模块的实例方法被包含在包含类的实例方法中.即,除了您的工作示例使用匿名模块这相当于:
module M1
def lab
puts 'm'
end
end
class Foo
include M1
def lab
super
puts 'c'
end
end
Run Code Online (Sandbox Code Playgroud)
接下来,想想是什么class_eval.它在类或模块的上下文中评估给定的代码.即它就像你重新打开模块并键入传递给它的代码一样class_eval.所以MyModule = Module.new { class_eval "def lab; puts 'm' end" }相当于
module MyModule
def lab
puts 'm'
end
end
Run Code Online (Sandbox Code Playgroud)
希望这能解释有效的案例.
当您使用时,instance_eval您正在评估接收对象的上下文中的代码(在本例中是模块的实例),因此MyMod2 = Module.new { instance_eval "def lab; puts 'm' end" }等效于
module MyMod2
def MyMod2.lab
puts 'm'
end
end
Run Code Online (Sandbox Code Playgroud)
即它创建了一个模块方法,您可以通过它调用此MyMod2.lab方法,并且不会将此类方法作为实例方法添加include.
请注意:这个答案从我写给前一个问题的答案中借用了一些解释,这个问题询问了与Ruby编程语言书中的一个例子有关的instance_eval与class_eval.您可能会发现答案也很有用.