Skip to content

Instantly share code, notes, and snippets.

@rhodee
Last active August 29, 2015 13:57
Show Gist options
  • Save rhodee/9656703 to your computer and use it in GitHub Desktop.
Save rhodee/9656703 to your computer and use it in GitHub Desktop.
A tested, dynamic approach to building configuration objects on the fly
class Configurator
def self.configure(&block)
configuration ||= new
configuration.instance_eval(&block)
return configuration
end
def respond_to_missing?(method_name, include_private = false)
super unless self.instance_variables.include?(convert_method_to_symbol(method_name))
end
def method_missing(m, *args, &block)
super(m, *args, &block) if respond_to?(m)
ivar = convert_method_to_symbol(m)
data = args.size == 1 ? args.first : args
#define getter, setter and predicate methods
self.class.__send__(:attr_accessor, ivar)
self.class.__send__(:define_method, "#{ivar}?", proc { !!data })
#set the value
instance_variable_set("@#{ivar}", data)
self
end
def convert_method_to_symbol(meth)
meth.to_s.gsub('=', '').to_sym
end
end
#Configurator.configure do |conf|
# conf.port = 8080
# conf.hostname = 'testing'
# conf.password = '$3(r3t'
#end
require 'minitest/autorun'
require 'minitest/pride'
class TestConfigurator < Minitest::Test
def test_config_methods
@configuration = Configurator.configure { |c| c.foo = 'meh' }
assert_includes @configuration.methods, :foo
assert_includes @configuration.methods, :foo?
assert_includes @configuration.methods, :foo=
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment