module Gapic::Config

Config is a simple DSL for creating Configuration classes.

@example

require "gapic/config"

class SampleConfig
  extend Gapic::Config

  config_attr :name,   nil,         String, nil
  config_attr :active, true,        true, false
  config_attr :count,  nil,         Numeric, nil
  config_attr :env,    :production, String, Symbol

  def initialize parent_config = nil
    @parent_config = parent_config unless parent_config.nil?
    yield self if block_given?
  end
end

config = SampleConfig.new

config.name             #=> nil
config.name = "thor"    #=> "thor"
config.name             #=> "thor"
config.name = :thor     # ArgumentError

Public Instance Methods

config_attr(name, default, *valid_values, &validator) click to toggle source

Add configuration attribute methods to the configuratin class.

@param [String, Symbol] key The name of the option @param [Object, nil] initial Initial value (nil is allowed) @param [Hash] opts Validation options

# File lib/gapic/config.rb, line 51
def config_attr name, default, *valid_values, &validator
  name = String(name).to_sym
  name_setter = "#{name}=".to_sym
  raise NameError, "invalid config name #{name}" if name !~ /^[a-zA-Z]\w*$/ || name == :parent_config
  raise NameError, "method #{name} already exists" if method_defined? name
  raise NameError, "method #{name_setter} already exists" if method_defined? name_setter

  raise ArgumentError, "validation must be provided" if validator.nil? && valid_values.empty?
  validator ||= ->(value) { valid_values.any? { |v| v === value } }

  name_ivar = "@#{name}".to_sym

  create_getter name_ivar, name, default
  create_setter name_ivar, name_setter, default, validator
end

Private Instance Methods

create_getter(name_ivar, name, default) click to toggle source
# File lib/gapic/config.rb, line 69
def create_getter name_ivar, name, default
  define_method name do
    return instance_variable_get name_ivar if instance_variable_defined? name_ivar

    if instance_variable_defined? :@parent_config
      parent = instance_variable_get :@parent_config
      return parent.__send__ name if parent.respond_to? name
    end

    default
  end
end
create_setter(name_ivar, name_setter, default, validator) click to toggle source
# File lib/gapic/config.rb, line 82
def create_setter name_ivar, name_setter, default, validator
  define_method name_setter do |new_value|
    valid_value = validator.call new_value
    if new_value.nil?
      # Always allow nil when a default value is present
      valid_value ||= !default.nil?
      valid_value ||= begin
        # Allow nil if parent config has the getter method.
        parent = instance_variable_get :@parent_config if instance_variable_defined? :@parent_config
        parent&.respond_to? name_setter
      end
    end
    raise ArgumentError unless valid_value

    if new_value.nil?
      remove_instance_variable name_ivar if instance_variable_defined? name_ivar
    else
      instance_variable_set name_ivar, new_value
    end
  end
end