Module: Yaks::Configurable
Overview
A “Configurable” class is one that keeps a configuration in a separate immutable object, of type class::Config. say you have
class MyMapper < Yaks::Mapper
# use yaks configuration DSL in here
end
The links, associations, etc, that you set up for MyMapper, will be available in MyMapper.config, which is an instance of Yaks::Mapper::Config.
Each configuration step, like link, has_many, will replace MyMapper.config with an updated version, discarding the old config.
By extending Configurable, a number of “macros” become available to describe the DSL that subclasses can use. See the docs for def_set. def_forward, and def_add.
Instance Attribute Summary collapse
-
#config ⇒ Object
Returns the value of attribute config.
Class Method Summary collapse
Instance Method Summary collapse
-
#def_add(name, options) ⇒ Object
Generate a DSL method that creates a certain type of domain object, and adds it to a list on the config.
-
#def_forward(mappings, *names) ⇒ Object
Forward a method to the config object.
-
#def_set(*method_names) ⇒ Object
Create a DSL method to set a certain config property.
- #inherited(child) ⇒ Object
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
21 22 23 |
# File 'lib/yaks/configurable.rb', line 21 def config @config end |
Class Method Details
.extended(child) ⇒ Object
23 24 25 |
# File 'lib/yaks/configurable.rb', line 23 def self.extended(child) child.config = child::Config.new end |
Instance Method Details
#def_add(name, options) ⇒ Object
Generate a DSL method that creates a certain type of domain object, and adds it to a list on the config.
def_add :fieldset, create: Fieldset, append_to: :fields
This will generate a fieldset method, which will call Fieldset.create, and append the result to config.fields
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/yaks/configurable.rb', line 76 def def_add(name, ) old_verbose, $VERBOSE = $VERBOSE, false # skip method redefinition warning define_singleton_method name do |*args, &block| defaults = .fetch(:defaults, {}) klass = .fetch(:create) if args.last.instance_of?(Hash) args[-1] = defaults.merge(args[-1]) else args << defaults end self.config = config.append_to( .fetch(:append_to), klass.create(*args, &block) ) end ensure $VERBOSE = old_verbose end |
#def_forward(mappings, *names) ⇒ Object
Forward a method to the config object. This assumes the method will return an updated config instance.
Either takes a list of methods to forward, or a mapping (hash) of source to destination method name.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/yaks/configurable.rb', line 57 def def_forward(mappings, *names) if mappings.instance_of? Hash mappings.each do |method_name, target| define_singleton_method method_name do |*args, &block| self.config = config.public_send(target, *args, &block) end end else def_forward([mappings, *names].map{|name| {name => name}}.inject(:merge)) end end |
#def_set(*method_names) ⇒ Object
Create a DSL method to set a certain config property. The generated method will take either a plain value, or a block, which will be captured and stored instead.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/yaks/configurable.rb', line 34 def def_set(*method_names) method_names.each do |method_name| define_singleton_method method_name do |arg = Undefined, &block| if arg.equal?(Undefined) unless block raise ArgumentError, "setting #{method_name}: no value and no block given" end self.config = config.with(method_name => block) else if block raise ArgumentError, "ambiguous invocation setting #{method_name}: give either a value or a block, not both." end self.config = config.with(method_name => arg) end end end end |
#inherited(child) ⇒ Object
27 28 29 |
# File 'lib/yaks/configurable.rb', line 27 def inherited(child) child.config = config end |