Class: Google::Cloud::Config

Inherits:
BasicObject
Defined in:
lib/google/cloud/config.rb

Overview

Configuration mechanism for Google Cloud libraries. A Config object contains a list of predefined keys, some of which are values and others of which are subconfigurations, i.e. categories. Field access is generally validated to ensure that the field is defined, and when a a value is set, it is validated for the correct type. Warnings are printed when a validation fails.

You generally access fields and subconfigs by calling accessor methods. Methods meant for "administration" such as adding options, are named with a trailing "!" or "?" so they don't pollute the method namespace. It is also possible to access a field using the [] operator.

Note that config objects inherit from BasicObject. This means it does not define many methods you might expect to find in most Ruby objects. For example, to_s, inspect, is_a?, instance_variable_get, and so forth.

Examples:

require "google/cloud/config"

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

config.opt1             #=> 10
config.opt1 = 20        #=> 20
config.opt1             #=> 20
config.opt1 = "hi"      #=> "hi" (but prints a warning)
config.opt1 = nil       #=> nil (but prints a warning)

config.opt2             #=> :one
config.opt2 = :two      #=> :two
config.opt2             #=> :two
config.opt2 = :four     #=> :four (but prints a warning)

config.opt3             #=> "hi"
config.opt3 = "hiho"    #=> "hiho"
config.opt3             #=> "hiho"
config.opt3 = "HI"      #=> "HI" (but prints a warning)

config.opt4             #=> "yo"
config.opt4 = :yo       #=> :yo (Strings and Symbols allowed)
config.opt4             #=> :yo
config.opt4 = 3.14      #=> 3.14 (but prints a warning)
config.opt4 = nil       #=> nil (no warning: nil allowed)

config.sub              #=> <Google::Cloud::Config>

config.sub.opt5         #=> false
config.sub.opt5 = true  #=> true  (true and false allowed)
config.sub.opt5         #=> true
config.sub.opt5 = nil   #=> nil (but prints a warning)

config.opt9 = "hi"      #=> "hi" (warning about unknown key)
config.opt9             #=> "hi" (no warning: key now known)
config.sub.opt9         #=> nil (warning about unknown key)

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object

Dynamic methods accessed as keys.



457
458
459
460
461
462
463
464
465
# File 'lib/google/cloud/config.rb', line 457

def method_missing name, *args
  name_str = name.to_s
  super unless name_str =~ /^[a-zA-Z]\w*=?$/
  if name_str.end_with? "="
    self[name_str[0...-1]] = args.first
  else
    self[name]
  end
end

Class Method Details

.config?(obj) ⇒ boolean

Determines if the given object is a config. Useful because Config does not define the is_a? method.

Returns:

  • (boolean)


104
105
106
# File 'lib/google/cloud/config.rb', line 104

def self.config? obj
  Config.send :===, obj
end

.create(show_warnings: true) {|config| ... } ⇒ Config

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

Parameters:

  • show_warnings (boolean) (defaults to: true)

    Whether to print warnings when a validation fails. Defaults to true.

Yields:

  • (config)

Returns:

  • (Config)

    The constructed Config object.



92
93
94
95
96
# File 'lib/google/cloud/config.rb', line 92

def self.create show_warnings: true
  config = new [], show_warnings: show_warnings
  yield config if block_given?
  config
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



308
309
310
311
312
313
314
# File 'lib/google/cloud/config.rb', line 308

def [] key
  key = resolve_key! key
  warn! "Key #{key.inspect} does not exist. Returning nil." unless @validators.key? key
  value = @values[key]
  value = value.call if Config::DeferredValue === value
  value
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



296
297
298
299
300
# File 'lib/google/cloud/config.rb', line 296

def []= key, value
  key = resolve_key! key
  validate_value! key, @validators[key], value
  @values[key] = value
end

#add_alias!(key, to_key) ⇒ Object

Cause a key to be an alias of another key. The two keys will refer to the same field.



235
236
237
238
239
240
241
# File 'lib/google/cloud/config.rb', line 235

def add_alias! key, to_key
  key = validate_new_key! key
  @values.delete key
  @defaults.delete key
  @validators[key] = to_key.to_sym
  self
end

#add_config!(key, config = nil, &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 to the subconfig.

You may also pass in a config object that already exists. This will "attach" that configuration in this location.

Parameters:

  • key (String, Symbol)

    The name of the subconfig

  • config (Config) (defaults to: nil)

    A config object to attach here. If not provided, creates a new config.

Returns:

  • (Config)

    self for chaining



218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/google/cloud/config.rb', line 218

def add_config! key, config = nil, &block
  key = validate_new_key! key
  if config.nil?
    config = Config.create(&block)
  elsif block
    yield config
  end
  @values[key] = config
  @defaults[key] = config
  @validators[key] = SUBCONFIG
  self
end

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

Add a value 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, which should return true or false to indicate whether the value is valid.
  • 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 valid 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.

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



188
189
190
191
192
193
194
195
196
197
# File 'lib/google/cloud/config.rb', line 188

def add_field! 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
  @values[key] = initial
  @defaults[key] = initial
  @validators[key] = validator
  self
end

#alias?(key) ⇒ Symbol?

Check if the given key has been explicitly added as an alias. If so, return the target, otherwise return nil.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (Symbol, nil)

    The alias target, or nil if not an alias.



357
358
359
360
# File 'lib/google/cloud/config.rb', line 357

def alias? key
  target = @validators[key.to_sym]
  target.is_a?(::Symbol) ? target : nil
end

#aliases!Array<Symbol>

Return a list of alias names.

Returns:

  • (Array<Symbol>)

    a list of alias names as symbols.



385
386
387
# File 'lib/google/cloud/config.rb', line 385

def aliases!
  @validators.keys.find_all { |key| @validators[key].is_a? ::Symbol }
end

#delete!(key = nil) ⇒ Object

Remove the given key from the configuration, deleting any validation and value. If the key is omitted, delete all keys. If the key is an alias, deletes the alias but leaves the original.

Parameters:

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

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



277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/google/cloud/config.rb', line 277

def delete! key = nil
  if key.nil?
    @values.clear
    @defaults.clear
    @validators.clear
  else
    @values.delete key
    @defaults.delete key
    @validators.delete key
  end
  self
end

#field?(key) ⇒ boolean Also known as: respond_to?

Check if the given key has been explicitly added as a field name.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (boolean)


335
336
337
# File 'lib/google/cloud/config.rb', line 335

def field? key
  @validators[key.to_sym].is_a? ::Proc
end

#fields!Array<Symbol>

Return a list of explicitly added field names.

Returns:

  • (Array<Symbol>)

    a list of field names as symbols.



367
368
369
# File 'lib/google/cloud/config.rb', line 367

def fields!
  @validators.keys.find_all { |key| @validators[key].is_a? ::Proc }
end

#reset!(key = nil) ⇒ Object

Restore the original default value of the given key. If the key is omitted, restore the original defaults for all keys, and all keys of subconfigs, recursively.

Parameters:

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

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



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/google/cloud/config.rb', line 251

def reset! key = nil
  if key.nil?
    @values.each_key { |k| reset! k }
  else
    key = key.to_sym
    if @defaults.key? key
      @values[key] = @defaults[key]
      @values[key].reset! if @validators[key] == SUBCONFIG
    elsif @values.key? key
      warn! "Key #{key.inspect} has not been added, but has a value. Removing the value."
      @values.delete key
    else
      warn! "Key #{key.inspect} does not exist. Nothing to reset."
    end
  end
  self
end

#subconfig?(key) ⇒ boolean

Check if the given key has been explicitly added as a subconfig name.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (boolean)


346
347
348
# File 'lib/google/cloud/config.rb', line 346

def subconfig? key
  @validators[key.to_sym] == SUBCONFIG
end

#subconfigs!Array<Symbol>

Return a list of explicitly added subconfig names.

Returns:

  • (Array<Symbol>)

    a list of subconfig names as symbols.



376
377
378
# File 'lib/google/cloud/config.rb', line 376

def subconfigs!
  @validators.keys.find_all { |key| @validators[key] == SUBCONFIG }
end

#to_h!Hash

Returns a nested hash representation of this configuration state, including subconfigs. Only explicitly added fields and subconfigs are included.

Returns:

  • (Hash)


412
413
414
415
416
417
418
419
# File 'lib/google/cloud/config.rb', line 412

def to_h!
  h = {}
  @validators.each_key do |k|
    v = @values[k]
    h[k] = Config.config?(v) ? v.to_h! : v.inspect
  end
  h
end

#to_s!String Also known as: inspect

Returns a string representation of this configuration state, including subconfigs. Only explicitly added fields and subconfigs are included.

Returns:

  • (String)


395
396
397
398
399
400
401
402
# File 'lib/google/cloud/config.rb', line 395

def to_s!
  elems = @validators.keys.map do |k|
    v = @values[k]
    vstr = Config.config?(v) ? v.to_s! : v.inspect
    " #{k}=#{vstr}"
  end
  "<Config:#{elems.join}>"
end

#value_set?(key) ⇒ boolean Also known as: option?

Check if the given key has been set in this object. Returns true if the key has been added as a normal field, subconfig, or alias, or if it has not been added explicitly but still has a value.

Parameters:

  • key (Symbol)

    The key to check for.

Returns:

  • (boolean)


324
325
326
# File 'lib/google/cloud/config.rb', line 324

def value_set? key
  @values.key? resolve_key! key
end