Skip to content

Instantly share code, notes, and snippets.

@alebian
Created August 3, 2017 20:15
Show Gist options
  • Save alebian/3981c84d4060ce3b322646e460343d1d to your computer and use it in GitHub Desktop.
Save alebian/3981c84d4060ce3b322646e460343d1d to your computer and use it in GitHub Desktop.
module Configurable
def self.with(*attrs)
not_provided = Object.new
config_class = Class.new do
attrs.each do |attr|
define_method attr do |value = not_provided, &block|
if value === not_provided && block.nil?
result = instance_variable_get("@#{attr}")
result.is_a?(Proc) ? instance_eval(&result) : result
else
instance_variable_set("@#{attr}", block || value)
end
end
end
attr_writer *attrs
end
class_methods = Module.new do
define_method :config do
@config ||= config_class.new
end
def configure(&block)
config.instance_eval(&block)
end
end
Module.new do
singleton_class.send :define_method, :included do |host_class|
host_class.extend class_methods
end
end
end
end
require_relative 'configurable'
class Test
include Configurable.with(:first, :second, :third)
end
Test.configure do
first "First"
second "Second"
third { "#{first} - #{second}" }
end
puts Test.config.first #=> First
puts Test.config.second #=> Second
puts Test.config.third #=> First - Second
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment