在紅寶石中是否有require
的版本,要麼加載整個文件,要麼根本沒有?Ruby中的全部或無要求?
的問題是,需要從頂部開始加載,如果它面臨着你最終未完成的定義問題,例如,下面仍然會加載一個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
裝載機的工作方式是獲取當前的文件列表,試圖要求他們一個接一個。如果任何文件失敗,它將保留在列表中,稍後再次嘗試。該代碼是這樣的:(除去簡單很多細節)
# 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
我最終會想把它加載,然後找到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
會解決它。
任何想法?
謝謝,我知道我可以在每個文件中使用`require`,但我希望它是_automatic_。我提出了一個複雜的解決方案(運行第二個ruby實例作爲沙箱來測試需求),但看起來這是最好的做法,所以我會去做:) – 2009-07-12 08:14:45