Ruby | シングルトンクラスを作る


include するだけで OK 。

require 'singleton'
class A
  include Singleton
end

検証

通常のクラス

当たり前だが、インスタンス生成のたびにオブジェクトIDは変わる。

class B
end
puts B.new.object_id # 70357495108880
puts B.new.object_id # 70357495108820
puts B.new.object_id # 70357495108760

シングルトンクラス

何度呼び出してもオブジェクトIDは一緒だ。
new ではなく特異メソッドの instance を呼ぶ。

puts A.instance.object_id # 70357495109120
puts A.instance.object_id # 70357495109120
puts A.instance.object_id # 70357495109120

信憑性

他クラスのインスタンスから、シングルトンクラスのインスタンスを呼び出しても、オブジェクトIDは変わらない。

class A
  include Singleton
end
class B
  def call_singleton_instance
    A.instance.object_id
  end
end
puts A.instance.object_id # 70180072059980
puts A.instance.object_id # 70180072059980
puts A.instance.object_id # 70180072059980

puts B.new.call_singleton_instance # 70180072059980
puts B.new.call_singleton_instance # 70180072059980
puts B.new.call_singleton_instance # 70180072059980

initialize

initialize も一度しかおこなわれない。

class A
  include Singleton

  def initialize
    puts 'initialized'
  end
end
A.instance # initialized
A.instance
A.instance

引数

initialize に引数を取ることはできないっぽい。
「世界にひとつのインスタンスを作るのに、引数なんか要らないよね」って理解した。

class A
  include Singleton

  def initialize(argument)
  end
end

特に親切なメッセージは出してくれないっぽい。

A.instance 'argument' # `instance': wrong number of arguments (given 1, expected 0) (ArgumentError)

A.instance # `instance': wrong number of arguments (given 1, expected 0) (ArgumentError)

環境

  • ruby 2.3.1

参考