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 |