Class: OpenCensus::Common::Config

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

Overview

OpenCensus configuration class.

Configuration mechanism for OpenCensus libraries. A Config object contains a list of predefined keys, some of which are values and others of which are subconfigurations, i.e. categories. Option values are generally validated to ensure they are the correct type.

You generally access fields and subconfigs by calling accessor methods. Only explicitly defined fields have these accessor methods defined. Methods meant for "administration" such as adding options, are always named with a trailing "!" or "?" so they don't pollute the method namespace.

Example:

config = OpenCensus::Common::Config.new do |c|
  c.add_option! :opt1, 10
  c.add_option! :opt2, :one, enum: [:one, :two, :three]
  c.add_option! :opt3, "hi", match: [String, Symbol]
  c.add_option! :opt4, "hi", match: /^[a-z]+$/, allow_nil: true
  c.add_config! :sub do |c2|
    c2.add_option! :opt5, false
  end
end

config.opt1             #=> 10
config.opt1 = 20        #=> 20
config.opt1             #=> 20
config.opt1 = "hi"      #=> exception (only Integer allowed)
config.opt1 = nil       #=> exception (nil not allowed)

config.opt2             #=> :one
config.opt2 = :two      #=> :two
config.opt2             #=> :two
config.opt2 = :four     #=> exception (not in allowed enum)
config.opt2 = nil       #=> exception (nil not allowed)

config.opt3             #=> "hi"
config.opt3 = "hiho"    #=> "hiho"
config.opt3             #=> "hiho"
config.opt3 = "HI"      #=> exception (regexp check failed)
config.opt3 = nil       #=> exception (nil not allowed)

config.opt4             #=> "yo"
config.opt4 = :yo       #=> :yo  (Strings and Symbols allowed)
config.opt4             #=> :yo
config.opt4 = 3.14      #=> exception (not in allowed types)
config.opt4 = nil       #=> nil  (nil explicitly allowed)

config.sub              #=> <OpenCensus::Common::Config>

config.sub.opt5         #=> false
config.sub.opt5 = true  #=> true  (true and false allowed)
config.sub.opt5         #=> true
config.sub.opt5 = nil   #=> exception (nil not allowed)

config.opt9             #=> exception (unknown key)
config.sub.opt9         #=> exception (unknown key)

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ Config

Constructs a Configuration object. If a block is given, yields self to the block, which makes it convenient to initialize the structure by making calls to #add_option!, #add_config!, and #add_alias!.

Yields:

  • (_self)

Yield Parameters:



85
86
87
88
# File 'lib/opencensus/common/config.rb', line 85

def initialize
  @fields = {}
  yield self if block_given?
end

Instance Method Details

#[](key) ⇒ Object

Get the option or subconfig with the given name.

Parameters:

  • key (Symbol, String)

    The option or subconfig name

Returns:

  • (Object)

    The option value or subconfig object



289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/opencensus/common/config.rb', line 289

def [] key
  key = key.to_sym
  unless @fields.key? key
    raise ArgumentError, "Key #{key.inspect} does not exist"
  end
  field = @fields[key]
  if field.is_a? Config
    field
  else
    field.value
  end
end

#[]=(key, value) ⇒ Object

Assign an option with the given name to the given value.

Parameters:

  • key (Symbol, String)

    The option name

  • value (Object)

    The new option value



270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/opencensus/common/config.rb', line 270

def []= key, value
  key = key.to_sym
  unless @fields.key? key
    raise ArgumentError, "Key #{key.inspect} does not exist"
  end
  field = @fields[key]
  if field.is_a? Config
    raise ArgumentError, "Key #{key.inspect} is a subconfig"
  end
  validate_value! key, field.validator, value
  field.value = value
end

#add_alias!(new_key, config: nil, key: nil) ⇒ Config

Add a field to this configuration that is an alias of some other object, which may be another field or another configuration. This will effectively become an alternate "path" to that same object.

The following cases are supported:

  • Alias another configuration at this key by providing a config parameter but not a key. The given configuration is effectively "attached" as a subconfiguration; both the original configuration path, and this new key, point to the same configuration object and share configuration data.
  • Alias another field of this current configuration by providing a key parameter but not a config. The new key simply refers to the same object (which may be an option or a subconfig) as the original key, and shares the same data.
  • Alias another field or another configuration, by providing both a config parameter and a key parameter.

Parameters:

  • new_key (String, Symbol)

    The key to alias.

  • config (Config, nil) (defaults to: nil)

    The original configuration.

  • key (String, Symbol, nil) (defaults to: nil)

    The original field name.

Returns:

  • (Config)

    self for chaining



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/opencensus/common/config.rb', line 193

def add_alias! new_key, config: nil, key: nil
  new_key = validate_new_key! new_key
  if config.nil? && key.nil?
    raise ArgumentError, "You must provide a config and/or key."
  end
  field =
    if key.nil?
      config
    else
      (config || self).raw_field! key
    end
  @fields[new_key] = field
  define_getter_method! new_key
  define_setter_method! new_key if field.is_a? Option
  self
end

#add_config!(key, &block) ⇒ Config

Add a subconfiguration field to this configuration.

You must provide a key, which becomes the method name that you use to navigate to the subconfig. Names may comprise only letters, numerals, and underscores, and must begin with a letter.

If you provide a block, the subconfig object is passed to the block, so you can easily add fields.

Parameters:

  • key (String, Symbol)

    The name of the subconfig

Returns:

  • (Config)

    self for chaining



161
162
163
164
165
166
# File 'lib/opencensus/common/config.rb', line 161

def add_config! key, &block
  key = validate_new_key! key
  @fields[key] = Config.new(&block)
  define_getter_method! key
  self
end

#add_option!(key, initial = nil, opts = {}, &block) ⇒ Config

Add an option field to this configuration.

You must provide a key, which becomes the field name in this config. Field names may comprise only letters, numerals, and underscores, and must begin with a letter. This will create accessor methods for the new configuration key.

You may pass an initial value (which defaults to nil if not provided).

You may also specify how values are validated. Validation is defined as follows:

  • If you provide a block or a :validator option, it is used as the validator. A proposed value is passed to the proc, and it should return true or false to indicate whether the value is acceptable.
  • If you provide a :match option, it is compared to the proposed value using the === operator. You may, for example, provide a class, a regular expression, or a range. If you pass an array, the value is accepted if any of the elements match.
  • If you provide an :enum option, it should be an Enumerable. A proposed value is accepted if it is included.
  • Otherwise if you do not provide any of the above options, then a default validation strategy is inferred from the initial value:
    • If the initial is true or false, then either boolean value is considered valid. This is the same as enum: [true, false].
    • If the initial is nil, then any object is considered valid.
    • Otherwise, any object of the same class as the initial value is considered valid. This is effectively the same as match: initial.class.
  • You may also provide the :allow_nil option, which, if set to true, alters any of the above validators to allow nil values. If the initial value is nil but a specific validator is provided via :match or :enum, then :allow_nil defaults to true, otherwise it defaults to false.

In many cases, you may find that the default validation behavior (interpreted from the initial value) is sufficient. If you want to accept any value, use match: Object.

Parameters:

  • key (String, Symbol)

    The name of the option

  • initial (Object) (defaults to: nil)

    Initial value (defaults to nil)

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

    Validation options

Returns:

  • (Config)

    self for chaining



136
137
138
139
140
141
142
143
144
145
# File 'lib/opencensus/common/config.rb', line 136

def add_option! key, initial = nil, opts = {}, &block
  key = validate_new_key! key
  opts[:validator] = block if block
  validator = resolve_validator! initial, opts
  validate_value! key, validator, initial
  @fields[key] = Option.new initial, initial, validator
  define_getter_method! key
  define_setter_method! key
  self
end

#delete!(key = nil) ⇒ Object

Remove the given key from the configuration. If the key is omitted, deletes all keys.

Note the actual object being referenced is not touched. So if a deleted option is an alias of some other option, the other option will remain and retain the setting. Similarly, if a subconfig is referenced elsewhere, it will remain accessible from that other location.

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    The key to delete. If omitted or nil, delete all fields and subconfigs.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/opencensus/common/config.rb', line 249

def delete! key = nil
  if key.nil?
    @fields.clear
  else
    key = key.to_sym
    unless @fields.key? key
      raise ArgumentError, "Key #{key.inspect} does not exist"
    end
    field = @fields.delete key
    singleton_class.send :remove_method, :"#{key}"
    singleton_class.send :remove_method, :"#{key}=" if field.is_a? Option
  end
  self
end

#key?(key) ⇒ boolean

Check if this Config object has a key of the given name, regardless of whether it is an option or a subconfig.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (boolean)

    true if the key exists.



331
332
333
# File 'lib/opencensus/common/config.rb', line 331

def key? key
  @fields.key? key.to_sym
end

#keys!Array<Symbol>

Return a list of valid keys, including both options and subconfigs.

Returns:

  • (Array<Symbol>)

    a list of keys as symbols.



358
359
360
# File 'lib/opencensus/common/config.rb', line 358

def keys!
  @fields.keys
end

#option?(key) ⇒ boolean

Check if this Config object has an option of the given name.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (boolean)

    true if the inquired key is a valid option for this Config object. False otherwise.



309
310
311
# File 'lib/opencensus/common/config.rb', line 309

def option? key
  @fields[key.to_sym].is_a? Option
end

#options!Array<Symbol>

Return a list of valid option names.

Returns:

  • (Array<Symbol>)

    a list of option names as symbols.



340
341
342
# File 'lib/opencensus/common/config.rb', line 340

def options!
  @fields.keys.find_all { |key| @fields[key].is_a? Option }
end

#reset!(key = nil) ⇒ Object

Restore the original default value of the given key. If the key refers to a subconfiguration, restore its contents, recursively. If the key is omitted, restore the original defaults for all keys, including subconfigurations recursively.

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    The key to reset. If omitted or nil, recursively reset all fields and subconfigs.



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/opencensus/common/config.rb', line 219

def reset! key = nil
  if key.nil?
    @fields.each_key { |k| reset! k }
  else
    key = key.to_sym
    unless @fields.key? key
      raise ArgumentError, "Key #{key.inspect} does not exist"
    end
    field = @fields[key]
    if field.is_a? Config
      field.reset!
    else
      field.value = field.default
    end
  end
  self
end

#subconfig?(key) ⇒ boolean

Check if this Config object has a subconfig of the given name.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (boolean)

    true if the inquired key is a valid subconfig of this Config object. False otherwise.



320
321
322
# File 'lib/opencensus/common/config.rb', line 320

def subconfig? key
  @fields[key.to_sym].is_a? Config
end

#subconfigs!Array<Symbol>

Return a list of valid subconfig names.

Returns:

  • (Array<Symbol>)

    a list of subconfig names as symbols.



349
350
351
# File 'lib/opencensus/common/config.rb', line 349

def subconfigs!
  @fields.keys.find_all { |key| @fields[key].is_a? Config }
end

#to_h!Hash

Returns a nested hash representation of this configuration state, including subconfigurations.

Returns:

  • (Hash)


386
387
388
389
390
391
392
# File 'lib/opencensus/common/config.rb', line 386

def to_h!
  result = {}
  @fields.each do |k, v|
    result[k] = v.is_a?(Config) ? v.to_h! : v.value
  end
  result
end

#to_s!String

Returns a string representation of this configuration state.

Returns:

  • (String)


367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/opencensus/common/config.rb', line 367

def to_s!
  elems = @fields.map do |k, v|
    vstr =
      if v.is_a? Config
        v.to_s!
      else
        v.value.inspect
      end
    " #{k}=#{vstr}"
  end
  "<Config#{elems.join}>"
end