Class: Vapir::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/vapir-common/config.rb

Overview

represents a entry in a heirarchy of configuration options

Direct Known Subclasses

HashConfigurationWithOtherStuff

Defined Under Namespace

Classes: BadKeyError, Error, InvalidValueError, NoValueError, Option

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent) {|_self| ... } ⇒ Configuration

creates a new Configuration with the given parent. if a block is given, this Configuration object will be yielded to it.

Yields:

  • (_self)

Yield Parameters:



71
72
73
74
75
76
77
78
79
80
# File 'lib/vapir-common/config.rb', line 71

def initialize(parent, &block)
  unless parent==nil || parent.is_a?(Configuration)
    raise TypeError, "expected parent to be a Configuration; got #{parent.inspect}"
  end
  @parent=parent
  @config_hash = {}
  @recognized_options = {}
  yield(self) if block_given?
  define_key_methods
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

if the method invoked looks like assignment (ends with an =), calls to #update with the given method as the key and its argument as the value. otherwise calls #read with the method as the key.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/vapir-common/config.rb', line 95

def method_missing(method, *args)
  method=method.to_s
  if method =~ /\A([a-z_][a-z0-9_]*)([=?!])?\z/i
    method = $1
    special = $2
  else # don't deal with any special character crap 
    return super
  end
  case special
  when nil
    raise ArgumentError, "wrong number of arguments retrieving #{method} (#{args.size} for 0)" unless args.size==0
    read(method)
  when '='
    raise ArgumentError, "wrong number of arguments setting #{method} (#{args.size} for 1)" unless args.size==1
    update(method, *args)
  #when '?' # no defined behavior for ? or ! at the moment
  #when '!'
  else
    return super
  end
end

Instance Attribute Details

#parentObject (readonly)

the parent Configuration in the heirarchy. may be nil if there is no parent.



68
69
70
# File 'lib/vapir-common/config.rb', line 68

def parent
  @parent
end

Instance Method Details

#[](key) ⇒ Object

alias for #read



117
118
119
# File 'lib/vapir-common/config.rb', line 117

def [](key)
  read(key)
end

#[]=(key, value) ⇒ Object

alias for #update



121
122
123
# File 'lib/vapir-common/config.rb', line 121

def []=(key, value)
  update(key, value)
end

#create(key, options = {}) ⇒ Object

creates a new key. options are passed to Option.new; see its documentation.



181
182
183
184
185
186
187
# File 'lib/vapir-common/config.rb', line 181

def create(key, options={})
  key=validate_key_format!(key)
  if recognized_key?(key)
    raise "already created key #{key}"
  end
  @recognized_options[key]= Option.new(key, options)
end

#create_update(key, value, options = {}) ⇒ Object

creates a new key and updates it with the given value. options are passed to Option.new.



206
207
208
209
# File 'lib/vapir-common/config.rb', line 206

def create_update(key, value, options={})
  create(key, options)
  update(key, value)
end

#define_key_methodsObject

this is redundant with #method_missing, really, but it makes autocomplete possible in irb



82
83
84
85
86
87
88
89
90
91
# File 'lib/vapir-common/config.rb', line 82

def define_key_methods
  recognized_keys.each do |recognized_key|
    (class << self; self; end).send(:define_method, recognized_key) do
      read(recognized_key)
    end
    (class << self; self; end).send(:define_method, "#{recognized_key}=") do |value|
      update recognized_key, value
    end
  end
end

#defined_hashObject

returns a hash of currently defined configuration keys and values



158
159
160
# File 'lib/vapir-common/config.rb', line 158

def defined_hash
  (@parent ? @parent.defined_hash : {}).merge(@config_hash).freeze
end

#defined_key?(key) ⇒ Boolean

returns true if the given key is defined on this Configuration or any of its ancestors.

Returns:

  • (Boolean)


150
151
152
# File 'lib/vapir-common/config.rb', line 150

def defined_key?(key)
  locally_defined_key?(key) || (parent && parent.defined_key?(key))
end

#defined_keysObject

returns an array of keys defined on the current configuration



154
155
156
# File 'lib/vapir-common/config.rb', line 154

def defined_keys
  recognized_keys.select{|key| defined_key?(key) }
end

#delete(key) ⇒ Object

deletes the given key from the hash. this does not affect any ancestor Configurations.



217
218
219
220
# File 'lib/vapir-common/config.rb', line 217

def delete(key)
  key = check_key key
  @config_hash.delete(key)
end

#locally_defined_key?(key) ⇒ Boolean

returns true if the given key is defined on this Configuration; returns false if not - note that this returns false if the given key is defined on an ancestor Configuration.

Returns:

  • (Boolean)


145
146
147
148
# File 'lib/vapir-common/config.rb', line 145

def locally_defined_key?(key)
  key = validate_key_format!(key)
  @config_hash.key?(key)
end

#read(key) ⇒ Object

reads the value for the given key. if no value is defined, raises NoValueError.



189
190
191
192
193
194
195
196
197
198
# File 'lib/vapir-common/config.rb', line 189

def read(key)
  key = recognize_key! key
  if @config_hash.key?(key)
    @config_hash[key]
  elsif @parent
    @parent.read(key)
  else
    raise NoValueError, "There is no value defined for key #{key}"
  end
end

#recognize_key!(key) ⇒ Object

assert that the given key must be recognized; if it is not recognized, an error should be raised.



136
137
138
139
140
141
142
# File 'lib/vapir-common/config.rb', line 136

def recognize_key!(key)
  key = validate_key_format!(key)
  unless recognized_key?(key)
    raise BadKeyError, "Unrecognized key: #{key}"
  end
  key
end

#recognized_key?(key) ⇒ Boolean

returns true if the given key is recognized; false otherwise. may raise BadKeyError if the given key isn’t even a valid format for a key.

Returns:

  • (Boolean)


130
131
132
133
# File 'lib/vapir-common/config.rb', line 130

def recognized_key?(key)
  key = validate_key_format!(key)
  recognized_keys.include?(key)
end

#recognized_keysObject

returns an array of configuration keys which are recognized (either locally or inherited from a parent)



125
126
127
# File 'lib/vapir-common/config.rb', line 125

def recognized_keys
  ((@parent ? @parent.recognized_keys : [])+@recognized_options.keys).uniq
end

#update(key, value) ⇒ Object

updates the given key with the given value.



200
201
202
203
204
# File 'lib/vapir-common/config.rb', line 200

def update(key, value)
  key = recognize_key! key
  value = recognized_options[key].validate! value
  @config_hash[key]=value
end

#update_hash(hash) ⇒ Object

takes a hash of key/value pairs and calls #update on each pair.



211
212
213
214
215
# File 'lib/vapir-common/config.rb', line 211

def update_hash(hash)
  hash.each do |k,v|
    update(k,v)
  end
end

#validate_key_format!(key) ⇒ Object

raises an error if the given key is not in an acceptable format. the key should be a string or symbol consisting of alphanumerics and underscorse, beginning with an alpha or underscore.



163
164
165
166
167
168
169
170
171
172
# File 'lib/vapir-common/config.rb', line 163

def validate_key_format!(key)
  unless key.is_a?(String) || key.is_a?(Symbol)
    raise BadKeyError, "key should be a String or Symbol; got #{key.inspect} (#{key.class})"
  end
  key=key.to_s.downcase
  unless key =~ /\A([a-z_][a-z0-9_]*)\z/
    raise BadKeyError, "key should be all alphanumeric/underscores, not starting with a number"
  end
  key
end

#with_config(hash, &block) ⇒ Object

temporarily set the given keys of this configuration to the given values, yield to the block, and restore to the original configuration before returning.



224
225
226
227
228
229
230
231
232
# File 'lib/vapir-common/config.rb', line 224

def with_config(hash, &block)
  begin
    orig_config_hash = @config_hash.dup
    update_hash hash
    return yield
  ensure
    @config_hash = orig_config_hash
  end
end