Class: Loquacious::Configuration
- Inherits:
-
Object
- Object
- Loquacious::Configuration
- Defined in:
- lib/loquacious/configuration.rb,
lib/loquacious/configuration/help.rb,
lib/loquacious/configuration/iterator.rb,
lib/loquacious/configuration/help/string_presenter.rb
Overview
A Configuration provides a “blank slate” for storing configuration properties along with descriptions and default values. Configurations are accessed by name, and hence, the configuration properties can be retrieved from any location in your code.
Each property has an associated description that can be displayed to the user via the Configuration::Help class. This is the main point of the Loquacious library - tell the user what all yoru configruation properties actually do!
Each configurationp property can also have a default value that is returned if no value has been set for that property. Each property should hae a sensible default - the user should not have to configure every property in order to use a piece of code.
Defined Under Namespace
Classes: DSL, Error, Help, Iterator
Instance Attribute Summary collapse
-
#__defaults ⇒ Object
readonly
Accessor for configuration defaults.
-
#__defaults_mode ⇒ Object
Flag to switch the configuration object into defaults mode.
-
#__desc ⇒ Object
readonly
Accessor for the description hash.
-
#__name ⇒ Object
Name for this configuration object.
-
#__parent ⇒ Object
Name of the parent configuration object, used for traversal.
-
#__transforms ⇒ Object
Hash holding the transform procs.
-
#__values ⇒ Object
readonly
Accessor for configuration values.
Class Method Summary collapse
-
.defaults_for(name, &block) ⇒ Object
call-seq: Configuration.defaults_for( name ) { block }.
-
.for(name, &block) ⇒ Object
call-seq: Configuration.for( name ) Configuration.for( name ) { block }.
-
.help_for(name, opts = {}) ⇒ Object
(also: help)
call-seq: Configuration.help_for( name, opts = {} ).
-
.parent_list(config) ⇒ Object
Returns a string array with the parent tree for the config.
-
.to_hash(config) ⇒ Object
call-seq: Configuration.to_hash( config ).
Instance Method Summary collapse
-
#[](key) ⇒ Object
Provides hash accessor notation for configuration values.
-
#[]=(key, value) ⇒ Object
Provides hash accessor notation for configuration values.
-
#__eigenclass_eval(code, file, line) ⇒ Object
Evaluate the given code string in the context of this object’s eigenclass (singleton class).
-
#__send(symbol, *args, &block) ⇒ Object
Only invoke public methods on the Configuration instances.
-
#initialize(&block) ⇒ Configuration
constructor
Create a new configuration object and initialize it using an optional block of code.
-
#merge!(other) ⇒ Object
Merge the contents of the other configuration into this one.
-
#method_missing(method, *args, &block) ⇒ Object
When invoked, an attribute reader and writer are defined for the method.
-
#parent_list ⇒ Object
Returns an array of the parents in descending order.
-
#to_hash ⇒ Object
Recursively convert the configuration object to a hash.
Constructor Details
#initialize(&block) ⇒ Configuration
Create a new configuration object and initialize it using an optional block of code.
162 163 164 165 166 167 168 169 170 |
# File 'lib/loquacious/configuration.rb', line 162 def initialize( &block ) @__desc = Hash.new @__values = Hash.new @__defaults = Hash.new @__transforms = Hash.new @__defaults_mode = false @__parent = nil DSL.evaluate(:config => self, &block) if block end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
When invoked, an attribute reader and writer are defined for the method. Any arguments given are used to set the value of the attributes. If a block is given, then the attribute is a nested configuration and the block is evaluated in the context of a new configuration object.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/loquacious/configuration.rb', line 178 def method_missing( method, *args, &block ) m = method.to_s.delete('=').to_sym __eigenclass_eval "def #{m}=( value ) @__values[#{m.inspect}] = value; end", __FILE__, __LINE__ __eigenclass_eval <<-CODE, __FILE__, __LINE__+1 def #{m}( *args, &block ) value = @__values[#{m.inspect}] if args.empty? and !block return value if value.kind_of?(Configuration) value = @__defaults[#{m.inspect}] if value.kind_of?(Loquacious::Undefined) and @__defaults.has_key? #{m.inspect} if Loquacious.env_config env_name = Loquacious::Utility.env_var_name(__method__, self) if ENV.has_key? env_name if @__transforms.has_key? __method__ return @__transforms[__method__].call ENV[env_name] else return ENV[env_name] end end end return value.respond_to?(:call) ? value.call : value end if block v = DSL.evaluate(:parent_config => self, :config_name => __method__.to_s, :defaults_mode => __defaults_mode, &block) if value.kind_of?(Configuration) value.merge! v else @__values[#{m.inspect}] = v end else v = (1 == args.length ? args.first : args) if __defaults_mode @__defaults[#{m.inspect}] = v else @__values[#{m.inspect}] = v end end end CODE __desc[m] = nil unless __desc.has_key? m default = ((__defaults_mode or args.empty?) and !block) ? Loquacious::Undefined.new(m.to_s) : nil self.__send("#{m}=", default) self.__send("#{m}", *args, &block) end |
Instance Attribute Details
#__defaults ⇒ Object (readonly)
Accessor for configuration defaults
144 145 146 |
# File 'lib/loquacious/configuration.rb', line 144 def __defaults @__defaults end |
#__defaults_mode ⇒ Object
Flag to switch the configuration object into defaults mode. This allows default values to be set instead regular values.
148 149 150 |
# File 'lib/loquacious/configuration.rb', line 148 def __defaults_mode @__defaults_mode end |
#__desc ⇒ Object (readonly)
Accessor for the description hash.
138 139 140 |
# File 'lib/loquacious/configuration.rb', line 138 def __desc @__desc end |
#__name ⇒ Object
Name for this configuration object
151 152 153 |
# File 'lib/loquacious/configuration.rb', line 151 def __name @__name end |
#__parent ⇒ Object
Name of the parent configuration object, used for traversal
154 155 156 |
# File 'lib/loquacious/configuration.rb', line 154 def __parent @__parent end |
#__transforms ⇒ Object
Hash holding the transform procs
157 158 159 |
# File 'lib/loquacious/configuration.rb', line 157 def __transforms @__transforms end |
#__values ⇒ Object (readonly)
Accessor for configuration values
141 142 143 |
# File 'lib/loquacious/configuration.rb', line 141 def __values @__values end |
Class Method Details
.defaults_for(name, &block) ⇒ Object
call-seq:
Configuration.defaults_for( name ) { block }
Set the default values for the configuration associated with the given name. A block is required by this method.
Default values do not interfere with normal configuration values. If both are defined for a particualr configruation setting, then the regular configuration value will be returned.
Defaults allow the user to define configuration values before the library defaults have been loaded. They prevent library defaults from overriding user settings.
64 65 66 67 68 69 70 71 72 |
# File 'lib/loquacious/configuration.rb', line 64 def defaults_for( name, &block ) raise "defaults require a block" if block.nil? if @table.has_key? name DSL.evaluate(:config => @table[name], :defaults_mode => true, &block) else @table[name] = DSL.evaluate(:config_name => name, :defaults_mode => true, &block) end end |
.for(name, &block) ⇒ Object
call-seq:
Configuration.for( name )
Configuration.for( name ) { block }
Returns the configuration associated with the given name. If a block is given, then it will be used to create the configuration.
The same name can be used multiple times with different configuration blocks. Each different block will be used to add to the configuration; i.e. the configurations are additive.
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/loquacious/configuration.rb', line 38 def for( name, &block ) if block.nil? return @table.has_key?(name) ? @table[name] : nil end if @table.has_key? name DSL.evaluate(:config_name => name, :config => @table[name], &block) else @table[name] = DSL.evaluate(:config_name => name, &block) end end |
.help_for(name, opts = {}) ⇒ Object Also known as: help
call-seq:
Configuration.help_for( name, opts = {} )
Returns a Help instance for the configuration associated with the given name. See the Help#initialize method for the options that can be used with this method.
81 82 83 |
# File 'lib/loquacious/configuration.rb', line 81 def help_for( name, opts = {} ) ::Loquacious::Configuration::Help.new(name, opts) end |
.parent_list(config) ⇒ Object
Returns a string array with the parent tree for the config
111 112 113 114 115 116 117 118 119 |
# File 'lib/loquacious/configuration.rb', line 111 def parent_list(config) current_parent = config.__parent parents = [] until current_parent.nil? do parents.unshift current_parent.__name current_parent = current_parent.__parent end parents end |
.to_hash(config) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/loquacious/configuration.rb', line 91 def to_hash( config ) cache = { nil => {} } Iterator.new(config).each do |node| ary = node.name.split('.') name = ary.pop.to_sym parent = ary.empty? ? nil : ary.join('.') if node.config? cache[node.name] = cache[parent][name] = {} else cache[parent][name] = node.obj end end return cache[nil] end |
Instance Method Details
#[](key) ⇒ Object
Provides hash accessor notation for configuration values.
config = Configuration.for('app') {
port 1234
}
config[:port] #=> 1234
config.port #=> 1234
291 292 293 |
# File 'lib/loquacious/configuration.rb', line 291 def []( key ) self.__send(key) end |
#[]=(key, value) ⇒ Object
Provides hash accessor notation for configuration values.
config = Configuration.for('app')
config[:port] = 8808
config.port #=> 8808
301 302 303 |
# File 'lib/loquacious/configuration.rb', line 301 def []=( key, value ) self.__send(key, value) end |
#__eigenclass_eval(code, file, line) ⇒ Object
Evaluate the given code string in the context of this object’s eigenclass (singleton class).
240 241 242 243 244 245 |
# File 'lib/loquacious/configuration.rb', line 240 def __eigenclass_eval( code, file, line ) ec = class << self; self; end ec.module_eval code, file, line rescue StandardError Kernel.raise Error, "cannot evalutate this code:\n#{code}\n" end |
#__send(symbol, *args, &block) ⇒ Object
Only invoke public methods on the Configuration instances.
229 230 231 232 233 234 235 |
# File 'lib/loquacious/configuration.rb', line 229 def __send( symbol, *args, &block ) if self.respond_to? symbol self.__send__(symbol, *args, &block) else self.method_missing(symbol, *args, &block) end end |
#merge!(other) ⇒ Object
Merge the contents of the other configuration into this one. Values from the other configuratin will overwite values in this configuration.
This function is recursive. Nested configurations will be merged with their counterparts in the other configuration.
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/loquacious/configuration.rb', line 254 def merge!( other ) return self if other.equal? self Kernel.raise Error, "can only merge another Configuration" unless other.kind_of?(Configuration) other_values = other.__values other_defaults = other.__defaults other.__desc.each do |key,desc| value = @__values[key] other_value = other_values[key] if value.kind_of?(Configuration) and other_value.kind_of?(Configuration) value.merge! other_value elsif !other_value.kind_of?(Loquacious::Undefined) self.__send__(key, other_value) end if other_defaults.has_key? key @__defaults[key] = other_defaults[key] end if desc __desc[key] = desc end end self end |
#parent_list ⇒ Object
Returns an array of the parents in descending order
312 313 314 |
# File 'lib/loquacious/configuration.rb', line 312 def parent_list ::Loquacious::Configuration.parent_list(self) end |
#to_hash ⇒ Object
Recursively convert the configuration object to a hash.
307 308 309 |
# File 'lib/loquacious/configuration.rb', line 307 def to_hash ::Loquacious::Configuration.to_hash(self) end |