在我看来,对于instance_eval,类作用域变成了单例类,也称为目标对象的特征类。因此,在对象的单例类上创建的实例方法将成为该对象的单例方法。我的意思是以下两个代码片段产生预期结果
class TestClass; end
使用特征类
class TestClass
class << self
def class_method
"class_method of TestClass"
end
end
end
使用instance_eval
TestClass.instance_eval do
def class_method2
"class_method of TestClass"
end
end
这样我们就可以调用TestClass.class_method和TestClass.class_method2并得到相应的结果。 现在假设我们有一个模块 TestModule
module TestModule
def instance_method
" instance_method from TestModule"
end
end
现在,如果我们将此模块包含在 eigen 类中,那么我们可以将instance_method 作为 TestClass 的类方法进行访问
class TestClass
class << self
include TestModule
end
end
因此 TestClass.instance_method 将按预期工作。
但是如果我们使用instance_eval做同样的事情,它就会失败。请检查以下代码片段
TestClass.instance_eval do
include TestModule
end
当我尝试调用 TestClass.instance_method 时,出现以下错误。
ArgumentError: wrong number of arguments(0 for 1)
有人能解释一下问题是什么以及其背后的内部逻辑是什么吗?我非常感谢您提供的任何帮助。
最佳答案
这是因为如果你使用include
,当前类是什么并不重要,重要的是self
指向什么(include
是在 self
上调用的方法(如果您没有指定显式接收者),在您的示例中,self
指向 TestClass
,因此 TestModule#instance_method
成为 TestClass
的实例方法,如下例所示:
class TestClass
end
module TestModule
def test_method
'test'
end
end
TestClass.instance_eval { include TestModule }
TestClass.new.test_method
# => "test"
关于ruby - ruby eigen 类中的模块包含,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27438542/