模块 Singleton
Singleton
模块实现了 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 以引发 TypeErrors 以防止克隆或复制。
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
公共类方法
_load() 点击以切换源代码
默认情况下调用 instance()。覆盖以保留单例状态。
# File lib/singleton.rb, line 166
instance() 点击切换源代码
返回单例实例。
# File lib/singleton.rb, line 170
私有类方法
append_features(mod) 点击切换源代码
调用超类方法
# File lib/singleton.rb, line 149 def append_features(mod) # help out people counting on transitive mixins unless mod.instance_of?(Class) raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}" end super end
included(klass) 点击切换源代码
调用超类方法
# File lib/singleton.rb, line 157 def included(klass) super klass.private_class_method :new, :allocate klass.extend SingletonClassMethods Singleton.__init__(klass) end
公共实例方法
_dump(depth = -1) 点击切换源代码
默认情况下,在序列化时不保留任何状态。
# File lib/singleton.rb, line 108 def _dump(depth = -1) '' end
clone() 点击切换源代码
引发 TypeError
以防止克隆。
# File lib/singleton.rb, line 98 def clone raise TypeError, "can't clone instance of singleton #{self.class}" end
dup() 点击切换源代码
引发 TypeError
以防止复制。
# File lib/singleton.rb, line 103 def dup raise TypeError, "can't dup instance of singleton #{self.class}" end