Spec-Zone.ru › Ruby 3.2

модуль 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

По умолчанию _dump(depth) Singleton возвращает пустую строку. Маршаллинг по умолчанию удалит информацию о состоянии, например, переменные экземпляра из экземпляра. Классы, использующие 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() Показать исходный код
# File lib/singleton.rb, line 171
  

По умолчанию вызывает instance(). Переопределите для сохранения состояния синглтона.

instance() Показать исходный код
# File lib/singleton.rb, line 175

Возвращает экземпляр синглтона.

Закрытые методы класса

append_features(mod) Показать исходный код
# File lib/singleton.rb, line 154
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 162
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() Показать исходный код
# File lib/singleton.rb, line 98
def clone
  raise TypeError, "can't clone instance of singleton #{self.class}"
end

Вызывает TypeError для предотвращения клонирования.

dup() Показать исходный код
# File lib/singleton.rb, line 103
def dup
  raise TypeError, "can't dup instance of singleton #{self.class}"
end

Вызывает TypeError для предотвращения дублирования.

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API