来自stdlib的Ruby单例。如何杀死一个实例

时间:2010-12-13 14:44:43

标签: ruby-on-rails 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时会创建一个新实例并且我收到消息“初始化”。

有没有办法实现我的要求?

由于

3 个答案:

答案 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