2012-08-15 101 views
1

在Rails應用程序中,我想檢查是否定義了一個常量,並在必要時自動加載它。 defined?運算符返回false直到自動加載發生。定義?用於自動加載類

defined? Foo # => false :(
Foo # => Foo 
defined? Foo # => true 

我目前的解決方法是這樣的:

begin 
    Foo # try to autoload 
    true 
rescue NameError 
    false 
end 

是否有更好的方法來檢查,如果一個常量的定義,但如果需要也自動加載它?


的理由要求:

爲Rails的Konacha JS測試框架應自動拿起燈具ruby文件(如果存在)。加載應該在Rails的自動加載機制中發生,所以它受益於自動加載(使用config.cache_classes = false)。

+0

您可能會從解釋*爲什麼*您試圖執行此操作中受益。它可能會給你一個更好的答案。 – deefour 2012-08-15 16:52:00

+0

完成。 :) ......... – 2012-08-15 17:14:16

回答

1

聽起來好像您正在嘗試創建一個could_be_defined?方法,該方法嘗試自動加載,然後按照您的指示返回truefalse

在您嘗試使用它之前,無法確定某個類是否存在。這是高度動態語言的優勢之一。不利因素是不確定性。

您的強制加載和測試方法是確定知道的唯一方法。一些模塊可能不會通過autoload進行聲明,但實際上可以根據需要生成。試圖預測可能存在或可能不存在的東西最多是不可靠的。

+0

有趣,謝謝。在我的代碼中仍然困擾着我的是NameError過於廣泛的救援。如果加載'Foo'會導致模塊定義中的某個NameError,它將不會傳播。我不確定是否有更好的方法(檢查異常消息之後)。 – 2012-08-15 17:50:06

+0

如果加載模塊導致異常,我不確定那是你的問題。這是一個錯誤。你不可能爲此承擔責任。 – tadman 2012-08-15 18:35:03

0

我有一個類似的問題,我根據約定加載推斷的常量。我遇到的問題是,這些類的定義中的任何錯誤都被吞噬了。

我想出了這一點:

def const_presence(const_name) 
    const_name.constantize 
rescue NameError => e 
    raise e unless e.message =~ /uninitialized constant #{const_name}/ 
end 

這將返回零,如果沒有定義的常量或常量,如果它是,但重要的是允許在加載後提出的不斷遇到的任何錯誤。