是否有一个版本的require
in ruby 可以加载整个文件,或者什么都不加载?
class A
问题是 require 从顶部开始加载,如果遇到问题,您最终会得到未完成的定义,例如,即使module C
未定义,以下内容仍会加载:
class B
include C
end
在我的特殊情况下,我有大量相互依赖的文件,以及一个加载这些文件的加载器。为了举例说明,我将简单地将文件集设置为 4 个文件(a.rb、b.rb、c.rb 和 w.rb)。以下是这些文件的列表:
# In file a.rb
class A
@foo = []
@foo.push("in A")
def self.inherited(subclass)
foo = @foo.dup
subclass.instance_eval do
@foo = foo
end
end
def self.get_foo
@foo
end
end
# In file b.rb
class B < A
include C # if C is not already defined, the following line will not get executed although B will be defined.
@foo.push("in B")
end
# In file c.rb
module C
end
# In file w.rb
class W < B
@foo.push("in W")
end
加载器通过获取当前文件的列表来工作,并尝试一个一个地要求它们。如果任何文件失败,它会保留在列表中并稍后重试。代码是这样的:(为简单起见,删除了很多细节)
# In file loader.rb
files = Dir["*.rb"].reject { |f| f =~ /loader/ }
files.sort! # just for the purpose of the example, to make them load in an order that causes the problem
files.reject! { |f| require(f) rescue nil } while files.size > 0
我最终希望它加载A,然后发现B不能单独加载(所以跳过它),然后加载C,然后发现W还不能加载(所以跳过它),然后回到B然后W .
在这种情况下,输出p W.get_foo
将是["in A", "in B", "in W"]
,这就是我想要的。
实际发生的是它加载 A,然后部分加载 B,然后是 C,然后当涉及到 W 时,它相信它可以加载它(因为 B 已经定义)。这会在不正确的时间触发self.inherited
代码,并复制尚未就绪的 值@foo
,从而将 的输出p W.get_foo
错误地设为["in A", "in W"]
。
有一个全有或全无require
将解决它。
有任何想法吗?