模块 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)
返回空字符串。默认情况下,编组会剥离状态信息,例如实例的实例变量。使用 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
公共类方法
源码
# File lib/singleton.rb, line 146 def self.module_with_class_methods SingletonClassMethods end