2010-12-13 65 views
1

我正在學習ruby,這是我的情況。來自stdlib的Ruby單例。如何殺死一個實例

require 'singleton' 
class Lab 
    include Singleton 
    def initialize 
    puts 'initializing' 
    end 
end 

l1 = Lab.instance 
l2 = Lab.instance 

即使我已經完成了兩次Lab.instance,我只收到一條消息「初始化」。這意味着單身人士正在工作。大!

開發模式下的Rails使用const_remove殺死所有常量,以便在下一次請求模型和控制器上重新加載。

我想在這裏嘗試類似的東西。我想殺死l1和l2,這樣當我做Lab.instance時,創建一個新實例,並且我得到消息「初始化」。

有沒有辦法實現我所要求的?

謝謝

回答

1

這只是一個想法,但如何實現自己的單身模塊?

module MyLittleSingleton 
    def instance(*args, &block) 
    @instance ||= new(*args, &block) 
    end 
    def reload_instance! 
    @instance = nil 
    end 
end 

class Lab 
    extend MyLittleSingleton 
end 

它不會爲你提供同樣的「安全」作爲正常辛格爾頓,但它可能是你需要的東西。

+0

滾動你自己的東西是永遠存在作爲最後的手段。感謝您的建議和代碼示例。 – 2010-12-13 15:47:34

0

如果您需要單身的一個全新的實例(例如,與它在測試過程中發揮不影響其他測試),您可以使用匿名子類:

Lab.instance # This writes "initializing" 

MyLab = Class.new(Lab) 

MyLab.instance # This writes "initializing" 
MyLab.instance # This writes nothing 

如果你真的要重置單身,你可以做以下,但你進入警告區,它不是公共API的一部分:

Lab.instance # This writes "initializing" 

# Do it at your own risks 
Singleton.__init__(Lab) 

Lab.instance # This writes "initializing" 
Lab.instance # This writes nothing 
1

的辛格爾頓混合,在使用相當簡單機制可以輕鬆地重新實施。如果你看看它的核心,你會發現它使用名爲@singleton__instance__的實例變量進行緩存。因此,重置這個變量應該能夠完成這項工作。因此,如果你嘗試這種類方法添加到您的類:

def self.reset 
    @singleton__instance__ = nil 
end 

你可以這樣做:

l1 = Lab.instance #=> initializing 
l2 = Lab.instance #=> nothing 
Lab.reset 
l3 = Lab.instance #=> initializing 
l4 = Lab.instance #=> nothing