[ruby/singleton] Simplify the implementation

(https://github.com/ruby/singleton/pull/7)

Remove `__init__` and move logic to `included`.
This commit is contained in:
Daniel Pepper 2023-06-02 17:35:11 -07:00 committed by git
parent 4e26ae3cb9
commit bebd05fb51
2 changed files with 20 additions and 17 deletions

View File

@ -112,7 +112,7 @@ module Singleton
module SingletonClassMethods # :nodoc: module SingletonClassMethods # :nodoc:
def clone # :nodoc: def clone # :nodoc:
Singleton.__init__(super) super.include(Singleton)
end end
# By default calls instance(). Override to retain singleton state. # By default calls instance(). Override to retain singleton state.
@ -121,31 +121,18 @@ module Singleton
end end
def instance # :nodoc: def instance # :nodoc:
return @singleton__instance__ if @singleton__instance__ @singleton__instance__ || @singleton__mutex__.synchronize { @singleton__instance__ ||= new }
@singleton__mutex__.synchronize {
return @singleton__instance__ if @singleton__instance__
@singleton__instance__ = new()
}
@singleton__instance__
end end
private private
def inherited(sub_klass) def inherited(sub_klass)
super super
Singleton.__init__(sub_klass) sub_klass.include(Singleton)
end end
end end
class << Singleton # :nodoc: class << Singleton # :nodoc:
def __init__(klass) # :nodoc:
klass.instance_eval {
@singleton__instance__ = nil
@singleton__mutex__ = Thread::Mutex.new
}
klass
end
private private
# extending an object with Singleton is a bad idea # extending an object with Singleton is a bad idea
@ -156,14 +143,19 @@ module Singleton
unless mod.instance_of?(Class) unless mod.instance_of?(Class)
raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}" raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}"
end end
super super
end end
def included(klass) def included(klass)
super super
klass.private_class_method :new, :allocate klass.private_class_method :new, :allocate
klass.extend SingletonClassMethods klass.extend SingletonClassMethods
Singleton.__init__(klass) klass.instance_eval {
@singleton__instance__ = nil
@singleton__mutex__ = Thread::Mutex.new
}
end end
end end

View File

@ -94,6 +94,13 @@ class TestSingleton < Test::Unit::TestCase
assert_same a, b assert_same a, b
end end
def test_inheritance_creates_separate_singleton
a = SingletonTest.instance
b = Class.new(SingletonTest).instance
assert_not_same a, b
end
def test_class_level_cloning_preserves_singleton_behavior def test_class_level_cloning_preserves_singleton_behavior
klass = SingletonTest.clone klass = SingletonTest.clone
@ -101,4 +108,8 @@ class TestSingleton < Test::Unit::TestCase
b = klass.instance b = klass.instance
assert_same a, b assert_same a, b
end end
def test_class_level_cloning_creates_separate_singleton
assert_not_same SingletonTest.instance, SingletonTest.clone.instance
end
end end