我愛the autoload functionality of Ruby;然而,它是going away in future versions of Ruby,因爲它從來沒有線程安全。自動加載類在Ruby中沒有它的`autoload`
所以現在我想假裝它已經走了,沒有它寫我的代碼,由實現我自己的延遲加載機制。我想以最簡單的方式實現它(我現在不關心線程安全性)。 Ruby應該允許我們這樣做。
讓我們開始通過增加一類的const_missing
:
class Dummy
def self.const_missing(const)
puts "const_missing(#{const.inspect})"
super(const)
end
end
將Ruby當我們嘗試引用在‘虛擬’是不可少的,例如,如果我們嘗試引用「虛擬恆定稱這種特殊方法: :你好「,它會撥打const_missing
與符號:Hello
。這正是我們需要的,所以我們把它進一步:
class Dummy
def self.const_missing(const)
if :OAuth == const
require 'dummy/oauth'
const_get(const) # warning: possible endless loop!
else
super(const)
end
end
end
現在,如果我們引用「虛擬:: OAuth的」,這將需要預計將定義「的「虛擬/ oauth.rb」文件Dummy :: OAuth「常量。還有當我們調用const_get
(因爲它可以調用const_missing
內部),但防範是這個問題的範圍無限循環的可能性。
最大的問題是,這種整體解決方案打破了,如果存在一個在頂級命名空間名爲「OAuth的」模塊。引用「Dummy :: OAuth」將跳過其const_missing
,並從頂層返回「OAuth」。大多數的Ruby實現也將作出有關此警告:
warning: toplevel constant OAuth referenced by Dummy::OAuth
This was reported as a problem way back in 2003,但我無法找到證據證明Ruby的核心團隊是有史以來關注。今天,大多數流行的Ruby實現都具有相同的行爲。
的問題是,const_missing
默默地支持恆定的跳過的頂級命名空間。如果使用Ruby的autoload
功能聲明瞭「Dummy :: OAuth」,則不會發生這種情況。任何想法如何解決這個問題?
這似乎是一個愚蠢的想法,但你可以看看'autoload'的C源?我相信你可以在Ruby源代碼的某處找到它。如果你不能直接使用Ruby,可以選擇創建一個C擴展(可以訪問解釋器的下層)。 – Linuxios 2012-01-29 14:48:41
這是一個選項。 – mislav 2012-01-29 14:54:10
聽起來像一個蠻力的事情,但你不能''remove_const'上的頂級類? – phoet 2012-01-29 15:34:54