Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Trying to handle Singleton in a more flexible way
=begin
PRO:
* Configuration is easily testable (you can reset the singleton before each test)
* Configuration keeps Singleton behavior outside of its responabilities
=end
class Configuration
def initialize(path: nil)
puts "#initialize"
@path = path
# do some stuff, for example load the yaml located at @path
end
# define here the required helper methods
end
# ==> nil
module ConfigurableSingleton
def self.included(base)
base.class_eval do
def self.setup(**options)
@instance = reference_class.new(options) unless @instance
end
def self.instance
@instance || raise('init with .setup first')
end
def self.reset
@instance = nil
end
private_class_method :new
def self.reference_class
@reference_class || raise('provide a reference class with .use_class')
end
def self.use_class(klass)
@reference_class = klass
end
end
end
end
# ==> nil
class ConfigurationProvider
include ConfigurableSingleton
use_class Configuration
end
# ==> Configuration
ConfigurationProvider.setup(path: 'foo')
# =#initialize
# ==> #<Configuration:0x007f91da102840 @path="foo">
ConfigurationProvider.instance
# ==> #<Configuration:0x007f91da102840 @path="foo">
ConfigurationProvider.reset
# ==> nil
ConfigurationProvider.setup(path: 'moo')
# =#initialize
# ==> #<Configuration:0x007f91da8b6be0 @path="moo">
ConfigurationProvider.instance
# ==> #<Configuration:0x007f91da8b6be0 @path="moo">
ConfigurationProvider.new
# =NoMethodError: private method `new' called for ConfigurationProvider:Class
# = from (irb):54
# = from /usr/bin/irb:12:in `<main>'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.