在线文档教程
Ruby 2.4

Singleton

module Singleton(模块 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 and Marshal(单例和编排)

默认情况下,Singleton 的 #_dump(深度)返回空字符串。默认情况下,编组将从实例中剥离状态信息,例如实例变量和污点状态。使用Singleton的类可以提供自定义 _load(str)和 _dump(深度)方法来保留实例的一些以前的状态。

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" a.taint 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

公共类方法

_load()显示源文件

默认情况下调用 instance()。覆盖保留单身状态。

# File lib/singleton.rb, line 172

私有类方法

append_features(mod)显示源文件

调用超类方法

# File lib/singleton.rb, line 153 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 161 def included(klass) super klass.private_class_method :new, :allocate klass.extend SingletonClassMethods Singleton.__init__(klass) end

公共实例方法

_dump(深度= -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