我正在尝试练习在Ruby模块中使用自动加载功能。我有两个模块A
和B
.我想在A
的命名空间中加载模块B
,但我收到一个未初始化的常量错误。这两个文件位于同一文件夹中。这是我的代码:
A.rb
module A
end
A.autoload(:B, "./b.rb")
A::B.test #this line causes the error.
B.rb
module B
def self.test
puts "test called"
end
end
错误:
Traceback (most recent call last):
a.rb:7:in `<main>': uninitialized constant A::B (NameError)
Did you mean? A::B
B
这是因为您需要在模块 A 中为模块 B 命名:
# b.rb
module A
module B
def self.test
puts "test called"
end
end
end
使用此代码,ruby a.rb
将按预期工作。
奇怪的是,您当前的代码实际上确实加载了B 文件,但只有在尝试访问不存在的A::B
时引发错误之后。让我解释一下:
- 您注册
A.autoload(:B, "./b.rb")
- 您调用
A::B
- 这将执行自动加载以获取B
(在顶层),但随后尝试评估A::B
,由于您定义B
的方式而失败。
例如,看看如果你保持b.rb
原来的样子会发生什么,a.rb
更改为以下内容(我不建议这样做,我只是解释行为):
module A
end
A.autoload(:B, "./b.rb")
begin
A::B.test # This errors, but still performs the autoload
rescue NameError
end
B.test # this works because of the autoload