我遇到了instance_eval
和模块包含的问题。
请查看以下代码:
module B
class C
def initialize
puts 'This is C'
end
end
def hello
puts 'hello'
end
end
class A
include B
def initialize(&block)
hello
C.new
instance_eval(&block)
end
end
A.new do
hello
C.new
end
当我运行此代码时,我得到了
hello
This is C
hello
-:25:in `block in ': uninitialized constant C (NameError)
from -:19:in `instance_eval'
from -:19:in `initialize'
from -:23:in `new'
from -:23:in `'
我知道它与绑定以及方法和对象如何绑定到类有关。我无法理解的是,如何在C
内访问A
,但在我评估block
时却无法访问{{1}}。我希望它们属于同一范围。
谢谢!
答案 0 :(得分:2)
在下面的代码中
A.new do
hello
C.new
end
您正在尝试创建C
的对象,就好像它是在类Object
的范围内定义的一样。不它不是。类C
的定义在模块B
的范围内定义。你需要明确地告诉B:C.new
。
以上解释是针对错误 - :25:in'block in':未初始化的常量C(NameError)。
我无法理解的是如何在A中访问C?
Module#constants
为您解答: -
返回 mod 中可访问的常量名称数组。除非将inherit参数设置为
false
,否则这包括任何包含的模块中的常量的名称(示例在部分的开头)。
看一下例子:
module M
X = 10
class D; Y = 10 ;end
end
class C
include M
def initialize
p self.class.constants
end
end
C.new
# >> [:X, :D]
现在申请你的例子:
module B
class C
def initialize
'This is C'
end
end
def hello
'hello'
end
end
class A
include B
def initialize(&block)
p self.class.constants
C.new # it will work
#instance_eval(&block)
end
end
A.new do
hello
C.new # but this will throw error.
end
# it confirms that C is accessible, within the method.
# That is the same reason you got the output "This is C"
# >> [:C]
希望有所帮助。