Class: VER::Options
- Inherits:
-
Object
- Object
- VER::Options
- Defined in:
- lib/ver/options.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 = Options.new(:foo)
def self.; @options; 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
name
and passblock
on 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/ver/options.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
147 148 149 150 151 152 153 154 |
# File 'lib/ver/options.rb', line 147 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
.
125 126 127 128 129 |
# File 'lib/ver/options.rb', line 125 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
134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/ver/options.rb', line 134 def []=(key, value) ks = key.to_sym if @hash.has_key? ks ns = @hash[ks] 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
.
89 90 91 |
# File 'lib/ver/options.rb', line 89 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/ver/options.rb', line 52 def dsl(&block) instance_eval(&block) if block self end |
#each_option(&block) ⇒ Object
166 167 168 |
# File 'lib/ver/options.rb', line 166 def each_option(&block) @hash.each(&block) end |
#each_pair ⇒ Object
170 171 172 173 174 |
# File 'lib/ver/options.rb', line 170 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.
102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/ver/options.rb', line 102 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
176 177 178 |
# File 'lib/ver/options.rb', line 176 def inspect @hash.inspect end |
#merge!(hash) ⇒ Object
156 157 158 159 160 |
# File 'lib/ver/options.rb', line 156 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 84 |
# File 'lib/ver/options.rb', line 79 def option(doc, key, value, other = {}, &block) trigger = block || other[:trigger] convert = {:doc => doc.to_s, :value => value} convert[:trigger] = trigger if trigger @hash[key.to_sym] = other.merge(convert) end |
#pretty_print(q) ⇒ Object
180 181 182 |
# File 'lib/ver/options.rb', line 180 def pretty_print(q) q.pp_hash @hash end |
#set_value(keys, value) ⇒ Object
118 119 120 121 122 |
# File 'lib/ver/options.rb', line 118 def set_value(keys, value) got = get(*keys) return got[:value] = value if got raise(IndexError, "There is no option available for %p" % [keys]) 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/ver/options.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
162 163 164 |
# File 'lib/ver/options.rb', line 162 def to_hash @hash end |
#trigger(key, &block) ⇒ Object
Add a block that will be called when a new value is set.
94 95 96 |
# File 'lib/ver/options.rb', line 94 def trigger(key, &block) @hash[key.to_sym][:trigger] = block end |