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)

Defined Under Namespace

Classes: Option

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:



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

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



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

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



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

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



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

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



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

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



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

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.



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

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

#inspectObject

Override the default inspect implementation.



407
408
409
# File 'lib/opencensus/common/config.rb', line 407

def inspect
  to_s!
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.



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

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.



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

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.



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

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.



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

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.



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

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.



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

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.



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

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

#to_hObject

Override the default to_h implementation.



416
417
418
# File 'lib/opencensus/common/config.rb', line 416

def to_h
  to_h!
end

#to_h!Hash

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

Returns:

  • (Hash)


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

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

#to_sObject

Override the default to_s implementation.



398
399
400
# File 'lib/opencensus/common/config.rb', line 398

def to_s
  to_s!
end

#to_s!String

Returns a string representation of this configuration state.

Returns:

  • (String)


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

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