我正在学习红宝石,这就是我的情况。
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时会创建一个新实例并且我收到消息“初始化”。
有没有办法实现我的要求?
由于
答案 0 :(得分:2)
Singleton混合使用一种非常简单的机制,您可以轻松地重新实现。如果您查看其核心,您将看到它使用名为@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
答案 1 :(得分:1)
这只是一个想法,但是如何实现自己的单例模块?
module MyLittleSingleton
def instance(*args, &block)
@instance ||= new(*args, &block)
end
def reload_instance!
@instance = nil
end
end
class Lab
extend MyLittleSingleton
end
它不会为您提供与普通Singleton相同的“安全性”,但它可能正是您所需要的。
答案 2 :(得分:0)
如果您需要一个全新的单例实例(例如,在测试期间使用它而不影响其他测试),您可以使用匿名子类:
Lab.instance # This writes "initializing"
MyLab = Class.new(Lab)
MyLab.instance # This writes "initializing"
MyLab.instance # This writes nothing
如果确实想重置您的单身人士,您可以执行以下操作,但输入警告区域,它不属于公共API:< / p>
Lab.instance # This writes "initializing"
# Do it at your own risks
Singleton.__init__(Lab)
Lab.instance # This writes "initializing"
Lab.instance # This writes nothing