Provides a minimal DSL to describe options with defaults and metadata.
The example below should demonstrate the major features, note that key lookup wanders up the hierarchy until there is a match found or the parent of the Options class is itself, in which case nil will be returned.
Usage:
class Calculator @options = Options.new(:foo) def self.options; @options; end options.dsl do o "Which method to use", :method, :plus o "Default arguments", :args, [1, 2] sub(:minus){ o("Default arguments", :args, [4, 3]) } end def self.calculate(method = nil, *args) method ||= options[:method] args = args.empty? ? options[method, :args] : args self.send(method, *args) end def self.plus(n1, n2) n1 + n2 end def self.minus(n1, n2) n1 - n2 end end Calculator.calculate # => 3 Calculator.options[:method] = :minus # => :minus Calculator.calculate # => 1 Calculator.calculate(:plus, 4, 5) # => 9
Retrieve only the :value from the value hash if found via keys.
# File lib/innate/options/dsl.rb, line 125 125: def [](*keys) 126: if value = get(*keys) 127: value.is_a?(Hash) ? value[:value] : value 128: end 129: end
Assign new :value to the value hash on the current instance.
TODO: allow arbitrary assignments
# File lib/innate/options/dsl.rb, line 134 134: def []=(key, value) 135: ks = key.to_sym 136: if @hash.has_key? ks 137: ns = @hash[ks] 138: ns[:value] = value 139: ns[:trigger].call(value) if ns[:trigger].respond_to?(:call) 140: elsif existing = get(key) 141: option(existing[:doc].to_s.dup, key, value) 142: else 143: raise(ArgumentError, "No key for %p exists" % [key]) 144: end 145: end
To avoid lookup on the parent, we can set a default to the internal Hash. Parameters as in {Options#o}, but without the key.
# File lib/innate/options/dsl.rb, line 89 89: def default(doc, value, other = {}) 90: @hash.default = other.merge(:doc => doc, :value => value) 91: end
Shortcut for instance_eval
# File lib/innate/options/dsl.rb, line 52 52: def dsl(&block) 53: instance_eval(&block) if block 54: self 55: end
# File lib/innate/options/dsl.rb, line 166 166: def each_option(&block) 167: @hash.each(&block) 168: end
# File lib/innate/options/dsl.rb, line 170 170: def each_pair 171: @hash.each do |key, values| 172: yield(key, self[key]) 173: end 174: end
Try to retrieve the corresponding Hash for the passed keys, will try to retrieve the key from a parent if no match is found on the current instance. If multiple keys are passed it will try to find a matching child and pass the request on to it.
# File lib/innate/options/dsl.rb, line 102 102: def get(key, *keys) 103: if keys.empty? 104: if value = @hash[key.to_sym] 105: value 106: elsif @parent != self 107: @parent.get(key) 108: else 109: nil 110: end 111: elsif sub_options = get(key) 112: sub_options.get(*keys) 113: end 114: end
# File lib/innate/options/dsl.rb, line 176 176: def inspect 177: @hash.inspect 178: end
# File lib/innate/options/dsl.rb, line 156 156: def merge!(hash) 157: hash.each_pair do |key, value| 158: set_value(key.to_s.split('.'), value) 159: end 160: end
# File lib/innate/options/dsl.rb, line 147 147: def method_missing(meth, *args) 148: case meth.to_s 149: when /^(.*)=$/ 150: self[$1] = args.first 151: else 152: self[meth] 153: end 154: end
Store an option in the Options instance.
@param [#] doc describing the purpose of this option @param [#] key used to access @param [Object] value may be anything @param [Hash] other optional Hash containing meta-data
:doc, :value keys will be ignored
# File lib/innate/options/dsl.rb, line 79 79: def option(doc, key, value, other = {}, &block) 80: trigger = block || other[:trigger] 81: convert = {:doc => doc.to_s, :value => value} 82: convert[:trigger] = trigger if trigger 83: @hash[key.to_sym] = other.merge(convert) 84: end
# File lib/innate/options/dsl.rb, line 180 180: def pretty_print(q) 181: q.pp_hash @hash 182: end
@param [Array] keys @param [Object] value
# File lib/innate/options/dsl.rb, line 118 118: def set_value(keys, value) 119: got = get(*keys) 120: return got[:value] = value if got 121: raise(IndexError, "There is no option available for %p" % [keys]) 122: end
Create a new Options instance with name and pass block on to its #. Assigns the new instance to the name Symbol on current instance.
# File lib/innate/options/dsl.rb, line 59 59: def sub(name, &block) 60: name = name.to_sym 61: 62: case found = @hash[name] 63: when Options 64: found.dsl(&block) 65: else 66: found = @hash[name] = Options.new(name, self).dsl(&block) 67: end 68: 69: found 70: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.