下面的代码:
module P; end
P.autoload(:Foo, "#{__dir__}/foo.rb")
P::Foo.new.foo # works well
P.send(:remove_const, :Foo)
P::Foo.new.foo # raising error
我已经为P::Foo
设置了autoload
,但是第二次它不起作用。为什么和如何?
即使我重置autoload
,它仍然不工作:
P.send(:remove_const, :Foo)
P.autoload(:Foo, "#{__dir__}/foo.rb")
P::Foo.new.foo # raising error
1条答案
按热度按时间pgccezyw1#
根据
Module#autoload
的文件:注册要在 mod 的命名空间中第一次访问 module(可能是字符串或符号)时加载的文件名(使用Kernel::require)。
根据
Kernel#require
的文件:加载给定的
name
,如果成功则返回true
,如果功能已加载则返回false
。您首先调用了
P::Foo
,它通过Kernel#require
“自动加载”了“#{dir}/foo.rb”文件。然后您删除了常量P::Foo
(在该文件中定义),但该特性已经加载,因此后续调用不会尝试并再次要求它,因为Kernel.require("#{__dir__}/foo.rb") #=> false
。这与明确要求相同,例如
p/foo.rb
p.rb
如果你想“强制”重载那个文件,你可以调用
Kernel#load
。