Class: Innate::Options
- Inherits:
-
Object
- Object
- Innate::Options
- Defined in:
- lib/innate/options/dsl.rb
Overview
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.new(:foo)
def self.; ; end
.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 ||= [:method]
args = args.empty? ? [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.[:method] = :minus
# => :minus
Calculator.calculate
# => 1
Calculator.calculate(:plus, 4, 5)
# => 9
Instance Method Summary collapse
-
#[](*keys) ⇒ Object
Retrieve only the :value from the value hash if found via
keys. -
#[]=(key, value) ⇒ Object
Assign new :value to the value hash on the current instance.
-
#default(doc, value, other = {}) ⇒ Object
To avoid lookup on the parent, we can set a default to the internal Hash.
-
#dsl(&block) ⇒ Object
Shortcut for instance_eval.
- #each_option(&block) ⇒ Object
- #each_pair ⇒ Object
-
#get(key, *keys) ⇒ Object
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.
-
#initialize(name, parent = self) {|_self| ... } ⇒ Options
constructor
A new instance of Options.
- #inspect ⇒ Object
- #merge!(hash) ⇒ Object
- #method_missing(meth, *args) ⇒ Object
-
#option(doc, key, value, other = {}, &block) ⇒ Object
(also: #o)
Store an option in the Options instance.
- #pretty_print(q) ⇒ Object
- #set_value(keys, value) ⇒ Object
-
#sub(name, &block) ⇒ Object
Create a new Options instance with
nameand passblockon to its #dsl. - #to_hash ⇒ Object
-
#trigger(key, &block) ⇒ Object
Add a block that will be called when a new value is set.
Constructor Details
#initialize(name, parent = self) {|_self| ... } ⇒ Options
Returns a new instance of Options.
45 46 47 48 49 |
# File 'lib/innate/options/dsl.rb', line 45 def initialize(name, parent = self) @name, @parent, = name, parent @hash = {} yield(self) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
142 143 144 145 146 147 148 149 |
# File 'lib/innate/options/dsl.rb', line 142 def method_missing(meth, *args) case meth.to_s when /^(.*)=$/ self[$1] = args.first else self[meth] end end |
Instance Method Details
#[](*keys) ⇒ Object
Retrieve only the :value from the value hash if found via keys.
122 123 124 125 126 |
# File 'lib/innate/options/dsl.rb', line 122 def [](*keys) if value = get(*keys) value.is_a?(Hash) ? value[:value] : value end end |
#[]=(key, value) ⇒ Object
Assign new :value to the value hash on the current instance.
TODO: allow arbitrary assignments
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/innate/options/dsl.rb', line 131 def []=(key, value) if ns = @hash[key.to_sym] ns[:value] = value ns[:trigger].call(value) if ns[:trigger].respond_to?(:call) elsif existing = get(key) option(existing[:doc].to_s.dup, key, value) else raise(ArgumentError, "No key for %p exists" % [key]) end end |
#default(doc, value, other = {}) ⇒ Object
To avoid lookup on the parent, we can set a default to the internal Hash. Parameters as in #o, but without the key.
88 89 90 |
# File 'lib/innate/options/dsl.rb', line 88 def default(doc, value, other = {}) @hash.default = other.merge(:doc => doc, :value => value) end |
#dsl(&block) ⇒ Object
Shortcut for instance_eval
52 53 54 55 |
# File 'lib/innate/options/dsl.rb', line 52 def dsl(&block) instance_eval(&block) if block self end |
#each_option(&block) ⇒ Object
161 162 163 |
# File 'lib/innate/options/dsl.rb', line 161 def each_option(&block) @hash.each(&block) end |
#each_pair ⇒ Object
165 166 167 168 169 |
# File 'lib/innate/options/dsl.rb', line 165 def each_pair @hash.each do |key, values| yield(key, self[key]) end end |
#get(key, *keys) ⇒ Object
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.
101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/innate/options/dsl.rb', line 101 def get(key, *keys) if keys.empty? if value = @hash[key.to_sym] value elsif @parent != self @parent.get(key) else nil end elsif = get(key) .get(*keys) end end |
#inspect ⇒ Object
171 172 173 |
# File 'lib/innate/options/dsl.rb', line 171 def inspect @hash.inspect end |
#merge!(hash) ⇒ Object
151 152 153 154 155 |
# File 'lib/innate/options/dsl.rb', line 151 def merge!(hash) hash.each_pair do |key, value| set_value(key.to_s.split('.'), value) end end |
#option(doc, key, value, other = {}, &block) ⇒ Object Also known as: o
Store an option in the Options instance.
79 80 81 82 83 |
# File 'lib/innate/options/dsl.rb', line 79 def option(doc, key, value, other = {}, &block) trigger = block || other[:trigger] convert = {:doc => doc.to_s, :value => value, :trigger => trigger} @hash[key.to_sym] = other.merge(convert) end |
#pretty_print(q) ⇒ Object
175 176 177 |
# File 'lib/innate/options/dsl.rb', line 175 def pretty_print(q) q.pp_hash @hash end |
#set_value(keys, value) ⇒ Object
117 118 119 |
# File 'lib/innate/options/dsl.rb', line 117 def set_value(keys, value) get(*keys)[:value] = value end |
#sub(name, &block) ⇒ Object
Create a new Options instance with name and pass block on to its #dsl. Assigns the new instance to the name Symbol on current instance.
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/innate/options/dsl.rb', line 59 def sub(name, &block) name = name.to_sym case found = @hash[name] when Options found.dsl(&block) else found = @hash[name] = Options.new(name, self).dsl(&block) end found end |
#to_hash ⇒ Object
157 158 159 |
# File 'lib/innate/options/dsl.rb', line 157 def to_hash @hash end |
#trigger(key, &block) ⇒ Object
Add a block that will be called when a new value is set.
93 94 95 |
# File 'lib/innate/options/dsl.rb', line 93 def trigger(key, &block) @hash[key.to_sym][:trigger] = block end |