Skip to content

Instantly share code, notes, and snippets.

@qen
Forked from justinko/gist:743458
Created May 30, 2012 22:26
Show Gist options
  • Save qen/2839327 to your computer and use it in GitHub Desktop.
Save qen/2839327 to your computer and use it in GitHub Desktop.
Common gem configuration implementations
class MyGem
class << self
attr_accessor :color
end
def self.configure(&block)
instance_eval(&block)
end
end
MyGem.configure do
self.color = true
end
puts MyGem.color # => true
Object.send(:remove_const, :MyGem)
########################################
class MyGem
def self.configure
yield configuration
end
def self.configuration
@configuration ||= Configuration.new
end
class Configuration
attr_accessor :color
end
end
MyGem.configure do |config|
config.color = true
end
puts MyGem.configuration.color # => true
Object.send(:remove_const, :MyGem)
########################################
class MyGem
def self.configure
yield configuration
end
def self.configuration
@configuration ||= Configuration.new
end
class Configuration
def initialize
@fields = Fields.new
end
def fields(&block)
if block
@fields.instance_eval(&block)
else
@fields.to_pretty
end
end
class Fields
def initialize
@fields = []
end
def to_pretty
{}.tap do |pretty|
@fields.each do |field|
pretty[field.name] = {:columns => field.columns}
end
end.inspect
end
def method_missing(sym, *args, &block)
@fields << Field.new(sym, &block)
end
class Field
attr_reader :name, :columns
def initialize(name, &block)
@name = name
@block = block
@columns = []
set_columns
end
def column(name)
@columns << name
end
def set_columns
instance_eval(&@block) if @block
end
end
end
end
end
MyGem.configure do |config|
config.fields do
dog :canine
cat :feline
rat :rodent do
column :birthdate
column :food_type
end
end
end
puts MyGem.configuration.fields # =>
# {
# :dog => { :columns => [] },
# :cat => { :columns => [] },
# :rat => { :columns => [:birthdate, :food_type] }
# }
########################################
module MyGem
def configure
yield configuration
end
def configuration
@configuration ||= Configuration.new
end
module_function :configuration, :configure
class Configuration
def initialize
@fields = Fields.new :fields
end
def fields(&block)
if block
@fields.instance_eval(&block)
else
@fields
end
end
def method_missing(sym, *args, &block)
value = (args.count == 1) ? args.first : args
value = Fields.new(sym, &block) if block
self.class.class_eval { attr_accessor sym }
self.instance_variable_set "@#{sym}", value
end
class Fields
def initialize(name, &block)
@__name = name
@__fields = {}
instance_eval(&block) if block
end
def method_missing(sym, *args, &block)
value = (args.count == 1) ? args.first : args
if block
@__fields[sym] = self.class.new(sym, &block)
value = @__fields[sym]
end
(class << self; self; end).class_eval { attr_accessor sym }
self.instance_variable_set "@#{sym}", value
end
end
end
end
MyGem.configure do |config|
config.simple_key 'value'
config.fields do
simple_key_example do
simple_key 'simple_value'
end
complex_key_example do
complex_key do
key1 'value1'
key2 'value2'
end
end
end
end
MyGem.configuration.simple_key # => 'value'
MyGem.configuration.fields.simple_key_example.simple_key # => 'simple_value'
MyGem.configuration.fields.complex_key_example.complex_key.key1 # => 'value1'
MyGem.configuration.fields.complex_key_example.complex_key.key2 # => 'value2'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment