Когда разумно использовать классы Singleton в Ruby?

Я читал о Singletons в Ruby. Мне никогда не приходилось использовать их раньше, но мне стало любопытно и решили посмотреть их, посмотреть, следует ли мне использовать их в прошлом, или, может быть, я смогу использовать их в будущем, если бы я знал, используется для.

Единственное, что я могу использовать, это:

  • ? Когда мне нужен специальный объект. Пример: "умный" Hash объект, который действует как обычный рубиновый хэш с несколькими дополнительными причудами.
  • Когда я хочу сделать так, может существовать только один экземпляр класса.

Тем не менее, я не уверен, что мне нужно было либо из вышеперечисленного.

Ответ 1

Обратите внимание, что смешивание классов в модуле Singleton функционально эквивалентно классу или модулю с методами класса и либо гарантированному вызову инициализации, либо встроенной инициализации. Сравните это использование Singleton:

require 'singleton'
class Bar
  include Singleton
  attr_reader :jam
  def initialize
    @jam = 42
  end
  def double
    @jam *= 2
  end
end

b1 = Bar.instance
b1.double
b2 = Bar.instance
b2.double
p b1.jam          #=> 168

с этим не магическим модулем:

module Foo
  @jam = 42
  def self.double
    @jam *= 2
  end
  def self.jam
    @jam
  end
end

Foo.double
Foo.double
p Foo.jam          #=> 168

В обоих случаях у вас есть один глобальный объект, который поддерживает состояние. (Поскольку каждая константа, которую вы создаете в глобальной области, включая классы и модули, является глобальным объектом.)

Единственное функциональное отличие заключается в том, что с Singleton вы задерживаете инициализацию объекта до первого запроса.

Итак, если у вас когда-либо были методы класса в классе или модуле, и вы используете их для изменения состояния этого объекта (например, класс, отслеживающий все подклассы, которые наследуются от него), вы по существу используете одноэлемент.

Ответ 2

В Ruby вы используете классы singleton все время. Фактически, каждый объект имеет одноэлементный класс. (Примечание: по соображениям производительности одноэлементные классы фактически создаются только при первом доступе к ним, но в том, что оптимизация производительности. Семантически каждый раз, когда вы пытаетесь взглянуть на одноэлементный класс, он будет там.)

Так называемые "методы класса", например, фактически не существуют в Ruby. Это просто обычные методы экземпляра класса singleton class. (Вместо этого просто проще сказать "метод класса".)

Каждый раз, когда вы определяете метод с синтаксисом def foo.bar, вы добавляете метод к одиночному классу foo.

Ответ 3

Как вы сказали, класс Singleton необходим, когда вам нужно иметь только один экземпляр класса. Очень хорошим примером класса Singleton в общепринятой структуре является класс Rails Logger.

Ответ 4

Ваша вторая точка маркера точно соответствует точке. подумайте о одиночном классе как о полностью статическом объекте. Булевы и Нулевые объекты в рубине являются примерами.