require
ファイル全体をロードするか、まったくロードしないバージョンの in ruby はありますか?
問題は、require が先頭から読み込みを開始することです。問題に直面した場合、未完成の定義になってしまいます。たとえば、次の例では、が定義されていなくclass A
てもを読み込みます。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
ローダーは、現在のファイルのリストを取得し、それらを 1 つずつ要求しようとします。いずれかのファイルが失敗した場合、そのファイルはリストに残り、後で再試行されます。コードは次のようなものです: (簡単にするために多くの詳細を削除しました)
# 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
で解決できます。
何か案は?