Class: Innate::Options

Inherits:
Object
  • Object
show all
Defined in:
/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/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 = 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

Instance Method Summary (collapse)

Constructor Details

- (Options) initialize(name, parent = self) {|_self| ... }

Returns a new instance of Options

Yields:

  • (_self)

Yield Parameters:



45
46
47
48
49
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/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

- (Object) method_missing(meth, *args)



147
148
149
150
151
152
153
154
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.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

- (Object) [](*keys)

Retrieve only the :value from the value hash if found via +keys+.



125
126
127
128
129
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 125

def [](*keys)
  if value = get(*keys)
    value.is_a?(Hash) ? value[:value] : value
  end
end

- (Object) []=(key, value)

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 '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.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

- (Object) default(doc, value, other = {})

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 '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 89

def default(doc, value, other = {})
  @hash.default = other.merge(:doc => doc, :value => value)
end

- (Object) dsl(&block)

Shortcut for instance_eval



52
53
54
55
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 52

def dsl(&block)
  instance_eval(&block) if block
  self
end

- (Object) each_option(&block)



166
167
168
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 166

def each_option(&block)
  @hash.each(&block)
end

- (Object) each_pair



170
171
172
173
174
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 170

def each_pair
  @hash.each do |key, values|
    yield(key, self[key])
  end
end

- (Object) get(key, *keys)

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 '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.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 sub_options = get(key)
    sub_options.get(*keys)
  end
end

- (Object) inspect



176
177
178
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 176

def inspect
  @hash.inspect
end

- (Object) merge!(hash)



156
157
158
159
160
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 156

def merge!(hash)
  hash.each_pair do |key, value|
    set_value(key.to_s.split('.'), value)
  end
end

- (Object) option(doc, key, value, other = {}, &block) Also known as: o

Store an option in the Options instance.

Parameters:

  • doc (#to_s)

    describing the purpose of this option

  • key (#to_sym)

    used to access

  • value (Object)

    may be anything

  • other (Hash) (defaults to: {})

    optional Hash containing meta-data :doc, :value keys will be ignored



79
80
81
82
83
84
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/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}
  convert[:trigger] = trigger if trigger
  @hash[key.to_sym] = other.merge(convert)
end

- (Object) pretty_print(q)



180
181
182
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 180

def pretty_print(q)
  q.pp_hash @hash
end

- (Object) set_value(keys, value)

Parameters:

  • keys (Array)
  • value (Object)

Raises:

  • (IndexError)


118
119
120
121
122
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.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

- (Object) sub(name, &block)

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 '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/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

- (Object) to_hash



162
163
164
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 162

def to_hash
  @hash
end

- (Object) trigger(key, &block)

Add a block that will be called when a new value is set.



94
95
96
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/options/dsl.rb', line 94

def trigger(key, &block)
  @hash[key.to_sym][:trigger] = block
end