模块 Singleton
用法¶ ↑
要使用 Singleton
,请将该模块包含在您的类中。
class Klass include Singleton # ... end
这确保了 Klass 只能创建一个实例。
a,b = Klass.instance, Klass.instance a == b # => true Klass.new # => NoMethodError - new is private ...
该实例在第一次调用 Klass.instance() 时创建。
class OtherKlass include Singleton # ... end ObjectSpace.each_object(OtherKlass){} # => 0 OtherKlass.instance ObjectSpace.each_object(OtherKlass){} # => 1
此行为在继承和克隆下保持不变。
实现¶ ↑
以上是通过以下方式实现的:
-
将 Klass.new 和 Klass.allocate 设置为私有。
-
重写 Klass.inherited(sub_klass) 和 Klass.clone() 以确保在继承和克隆时保留
Singleton
属性。 -
提供 Klass.instance() 方法,该方法每次调用都返回相同的对象。
-
重写 Klass._load(str) 以调用 Klass.instance()。
-
重写 Klass#clone 和 Klass#dup 以引发 TypeError,以防止克隆或复制。
Singleton
和 Marshal¶ ↑
默认情况下,Singleton 的 #_dump(depth) 返回空字符串。默认情况下,Marshal 会删除状态信息,例如实例的实例变量。使用 Singleton
的类可以提供自定义的 _load(str) 和 _dump(depth) 方法来保留实例的部分先前状态。
require 'singleton' class Example include Singleton attr_accessor :keep, :strip def _dump(depth) # this strips the @strip information from the instance Marshal.dump(@keep, depth) end def self._load(str) instance.keep = Marshal.load(str) instance end end a = Example.instance a.keep = "keep this" a.strip = "get rid of this" stored_state = Marshal.dump(a) a.keep = nil a.strip = nil b = Marshal.load(stored_state) p a == b # => true p a.keep # => "keep this" p a.strip # => nil
常量
- VERSION
公共类方法
_load() 点击切换源代码
默认情况下调用 instance()。重写以保留单例状态。
# File singleton.rb, line 190
instance() 点击切换源代码
返回单例实例。
# File singleton.rb, line 194
module_with_class_methods() 点击切换源代码
# File singleton.rb, line 146 def self.module_with_class_methods SingletonClassMethods end