2010-12-13 72 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