Module: Configliere::Define

Defined in:
lib/configliere/define.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object

Pretend that any #define'd parameter is a method

Examples:

Settings.define :foo
Settings.foo = 4
Settings.foo      #=> 4


165
166
167
168
169
170
171
172
173
174
# File 'lib/configliere/define.rb', line 165

def method_missing meth, *args
  meth.to_s =~ /^(\w+)(=)?$/ or return super
  name, setter = [$1.to_sym, $2]
  return(super) unless has_definition?(name)
  if setter && (args.size == 1)
    self[name] = args.first
  elsif (!setter) && args.empty?
    self[name]
  else super ; end
end

Instance Method Details

#define(param, pdefs = {}, &block) ⇒ Object

Define arbitrary attributes of a param, notably:

[:description] Documentation for the param, used in the --help message [:default] Sets a default value (applied immediately) [:env_var] Environment variable to adopt (applied immediately, and after +:default+) [:encrypted] Obscures/Extracts the contents of this param when serialized [:type] Converts param's value to the given type, just before the finally block is called [:finally] Block of code to postprocess settings or handle complex configuration. [:required] Raises an error if, at the end of calling resolve!, the param's value is nil.

Examples:

Settings.define :dest_time, :type => Date, :description => 'Arrival time. If only a date is given, the current time of day on that date is assumed.'
Settings.define 'delorean.power_source', :description => 'Delorean subsytem supplying power to the Flux Capacitor.'
Settings.define :password, :required => true, :obscure => true
Settings.define :danger, :finally => lambda{|c| if c[:delorean][:power_source] == 'plutonium' than c.danger = 'high' }

Parameters:

  • param

    the setting to describe. Either a simple symbol or a dotted param string.

  • definitions

    the defineables to set (:description, :type, :encrypted, etc.)



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/configliere/define.rb', line 23

def define param, pdefs={}, &block
  param = param.to_sym
  definitions[param].merge! pdefs
  self.use(:env_var)                      if pdefs.include?(:env_var)
  self.use(:encrypted)                    if pdefs.include?(:encrypted)
  self.use(:config_block)                 if pdefs.include?(:finally)
  self[param] = pdefs[:default]           if pdefs.include?(:default)
  self.env_vars param => pdefs[:env_var]  if pdefs.include?(:env_var)
  self.finally(&pdefs[:finally])          if pdefs.include?(:finally)
  self.finally(&block)                    if block
  self
end

#definition_of(param, attr = nil) ⇒ Hash, Object

all params with a value for the given aspect

Examples:

@config.define :has_description,  :description => 'desc 1', :foo => 'bar'
#
definition_of(:has_description)
# => {:description => 'desc 1', :foo => 'bar'}
definition_of(:has_description, :description)
# => 'desc 1'

Parameters:

  • aspect (Symbol)

    the aspect to list (:description, :type, :encrypted, etc.)

Returns:

  • (Hash, Object)


79
80
81
# File 'lib/configliere/define.rb', line 79

def definition_of(param, attr=nil)
  attr ? definitions[param.to_sym][attr] : definitions[param.to_sym]
end

#has_definition?(param, attr = nil) ⇒ Boolean

Is the param defined?

Returns:

  • (Boolean)


62
63
64
65
# File 'lib/configliere/define.rb', line 62

def has_definition?(param, attr=nil)
  if attr then definitions.has_key?(param.to_sym) && definitions[param].has_key?(attr)
  else         definitions.has_key?(param.to_sym) end
end

#params_with(aspect) ⇒ Hash

a hash holding every param with that aspect and its definition

Examples:

@config.define :has_description,      :description => 'desc 1'
@config.define :also_has_description, :description => 'desc 2'
@config.define :no_description,       :something_else => 'foo'
#
params_with(:description)
# => { :has_description => 'desc 1', :also_has_description => 'desc 2' }

Parameters:

  • aspect (Symbol)

    the aspect to list (:description, :type, :encrypted, etc.)

Returns:

  • (Hash)


95
96
97
98
99
100
101
102
# File 'lib/configliere/define.rb', line 95

def params_with(aspect)
  hsh = {}
  definitions.each do |param_name, param_def|
    next unless param_def.has_key?(aspect)
    hsh[param_name] = definition_of(param_name, aspect)
  end
  hsh
end

#resolve!Object

performs type coercion, continues up the resolve! chain



37
38
39
40
41
# File 'lib/configliere/define.rb', line 37

def resolve!
  resolve_types!
  super()
  self
end

#resolve_types!Object

Coerce all params with types defined to their proper form



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/configliere/define.rb', line 114

def resolve_types!
  params_with(:type).each do |param, type|
    val  = self[param]
    case
    when val.nil?            then val = nil
    when (type == :boolean)  then
      if ['false', false, 0, '0', ''].include?(val) then val = false else val = true end
    when (type == Array)
      if val.is_a?(String) then val = val.split(",") rescue nil ; end
    # for all following types, map blank/empty to nil
    when (val.respond_to?(:empty?) && val.empty?) then val = nil
    when (type == :filename) then val = File.expand_path(val)
    when (type == Float)     then val = val.to_f
    when (type == Integer)   then val = val.to_i
    when (type == Symbol)    then val = val.to_s.to_sym     rescue nil
    when (type == Regexp)    then val = Regexp.new(val)     rescue nil
    when ((val.to_s == 'now') && (type == Date))     then val = Date.today
    when ((val.to_s == 'now') && (type == DateTime)) then val = DateTime.now
    when ((val.to_s == 'now') && (type == Time))     then val = Time.now
    when [Date, Time, DateTime].include?(type)       then val = type.parse(val) rescue nil
    else warn("Unknown type #{type} given") # nothing
    end
    self[param] = val
  end
end

#validate!Object

ensures required types are defined, continues up the validate! chain



44
45
46
47
48
# File 'lib/configliere/define.rb', line 44

def validate!
  validate_requireds!
  super()
  true
end

#validate_requireds!Object

Check that all required params are present.



150
151
152
153
154
155
156
157
# File 'lib/configliere/define.rb', line 150

def validate_requireds!
  missing = []
  params_with(:required).each do |param, is_required|
    missing << param if self[param].nil? && is_required
  end
  return if missing.empty?
  raise "Missing values for: #{missing.map{|pn| d = definition_of(pn, :description) ; (d ? "#{pn} (#{d})" : pn.to_s) }.sort.join(", ")}"
end