class Appydays::Configurable::Installer

Public Class Methods

new(target, group_key) click to toggle source
# File lib/appydays/configurable.rb, line 69
def initialize(target, group_key)
  @target = target
  @group_key = group_key
  @settings = {}
  @after_config_hooks = []
end

Public Instance Methods

_converter(default, converter) click to toggle source
# File lib/appydays/configurable.rb, line 129
def _converter(default, converter)
  return converter if converter

  return ->(v) { v.to_s } if default.nil? || default.is_a?(String)
  return ->(v) { v.to_i } if default.is_a?(Integer)
  return ->(v) { v.to_f } if default.is_a?(Float)
  return ->(v) { v.casecmp("true").zero? } if [TrueClass, FalseClass].include?(default.class)
  raise TypeError, "Uncoercable type %p" % [default.class]
end
_group_key() click to toggle source
# File lib/appydays/configurable.rb, line 143
def _group_key
  return @group_key
end
_reset() click to toggle source
# File lib/appydays/configurable.rb, line 153
def _reset
  @settings.each do |k, v|
    @target.send("#{k}=".to_sym, v)
  end
  self._run_after_configured
end
_run_after_configured() click to toggle source
# File lib/appydays/configurable.rb, line 147
def _run_after_configured
  @after_config_hooks.each do |h|
    @target.instance_eval(&h)
  end
end
_set_value(name, value, side_effect) click to toggle source
# File lib/appydays/configurable.rb, line 116
def _set_value(name, value, side_effect)
  value = nil if value == ""
  # rubocop:disable Style/ClassVars
  self._target.class_variable_set("@@#{name}", value)
  # rubocop:enable Style/ClassVars
  self._target.instance_exec(value, &side_effect) if side_effect
  return value
end
_target() click to toggle source
# File lib/appydays/configurable.rb, line 139
def _target
  return @target
end
after_configured(&block) click to toggle source
# File lib/appydays/configurable.rb, line 125
def after_configured(&block)
  @after_config_hooks << block
end
setting(name, default, key: nil, convert: nil, side_effect: nil) click to toggle source

Define a setting for the receiver, which acts as an attribute accessor.

Params:

name: The name of the accessor/setting. default: The default value.

If `convert` is not supplied, this must be nil, or a string, int, float, or boolean,
so the parsed environment value can be converted/coerced into the same type as 'default'.
If convert is passed, that is used as the converter so the default value can be any type.

key: The key to lookup the config value from the environment.

If nil, use an auto-generated combo of the configuration key and method name.

convert: If provided, call it with the string value so it can be parsed.

For example, you can parse a string JSON value here.
Convert will not be called with the default value.

side_effect: If this setting should have a side effect,

like configuring an external system, it should happen in this proc/lambda.
It is called with the parsed/processed config value.

Note that only ONE conversion will happen, and

  • If converter is provided, it will be used with the environment value.

# File lib/appydays/configurable.rb, line 98
def setting(name, default, key: nil, convert: nil, side_effect: nil)
  installer = self

  @target.define_singleton_method(name) do
    self.class_variable_get("@@#{name}")
  end
  @target.define_singleton_method("#{name}=".to_sym) do |v|
    installer._set_value(name, v, side_effect)
  end

  key ||= "#{@group_key}_#{name}".upcase
  env_value = ENV.fetch(key, nil)
  converter = self._converter(default, convert)
  value = env_value.nil? ? default : converter[env_value]
  value = installer._set_value(name, value, side_effect)
  @settings[name] = value
end