Module: Calibrate::Configurable::ClassMethods

Included in:
Calibrate::Configurable
Defined in:
lib/calibrate/configurable/class-methods.rb

Overview

Describes class level DSL & machinery for working with configuration managment.

Examples:

class ConfExample
  include Configurable

  setting :foo
  settings :bar => 1, :baz => 3
  nil_fields :hoo, :ha, :harum
  required_fields :must

  def initialize
    setup_defaults
  end
end

ce = ConfExample.new
ce.bar #=> 1
ce.hoo #=> nil
ce.hoo = "hallo"
ce.check_required #=> raises error because :must and :foo aren't set

Instance Method Summary collapse

Instance Method Details

#default_value_for(name) ⇒ Object

Raises:



58
59
60
61
62
# File 'lib/calibrate/configurable/class-methods.rb', line 58

def default_value_for(name)
  field = (name)
  raise NoDefaultValue.new(name,self) unless field.is?(:defaulting)
  return field.default_value
end

#default_valuesObject



35
36
37
# File 'lib/calibrate/configurable/class-methods.rb', line 35

def default_values
  @default_values ||= []
end

#field_metadata(name) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/calibrate/configurable/class-methods.rb', line 48

def (name)
  field = default_values.find{|field| field.name == name}
  if field.nil? and Configurable > superclass
    superclass.(name)
  else
    field
  end
end

#field_namesObject



39
40
41
42
43
44
45
46
# File 'lib/calibrate/configurable/class-methods.rb', line 39

def field_names
  names = default_values.map{|field| field.name}
  if Configurable > superclass
    names | superclass.field_names
  else
    names
  end
end

#from_hash(obj, hash) ⇒ Object

XXX It’d be really nice if this could report unused fields



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/calibrate/configurable/class-methods.rb', line 196

def from_hash(obj, hash) #XXX It'd be really nice if this could report unused fields
  if Configurable > superclass
    superclass.from_hash(obj, hash)
  end
  default_values.each do |field|
    catch :next do
      key = field.reader_method.to_s
      value = hash.fetch(key.to_s) do
        key = key.to_sym
        hash.fetch(key) do
          throw :next
        end
      end

      existing_value = obj.__send__(field.reader_method)
      if Configurable === existing_value and value.is_a? Hash
        existing_value.from_hash(value)
      else
        obj.__send__(field.writer_method, value)
      end
    end
  end
end

#included(mod) ⇒ Object



220
221
222
# File 'lib/calibrate/configurable/class-methods.rb', line 220

def included(mod)
  mod.extend ClassMethods
end

#inspect_instance(instance, indent = "") ⇒ Object



28
29
30
31
32
33
# File 'lib/calibrate/configurable/class-methods.rb', line 28

def inspect_instance(instance, indent="")
  field_names.map do |name|
    meta = (name)
    "#{indent}#{meta.inspect_on(instance, indent * 2)}"
  end.join("\n")
end

#missing_required_fields_on(instance) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/calibrate/configurable/class-methods.rb', line 154

def missing_required_fields_on(instance)
  missing = []
  if Configurable > superclass
    missing = superclass.missing_required_fields_on(instance)
  end
  default_values.each do |field|
    if field.missing_on?(instance)
      missing << field.name
    else
      set_value = instance.__send__(field.reader_method)
      if Configurable === set_value
        missing += set_value.class.missing_required_fields_on(set_value).map do |sub_field|
          [field.name, sub_field].join(".")
        end
      end
    end
  end
  return missing
end

#nested(hash = nil, &block) ⇒ Object

Creates an anonymous Configurable - useful in complex setups for nested settings

Examples:

SSH options

setting :ssh => nested(:username => "me", :password => nil)


68
69
70
71
72
73
74
75
# File 'lib/calibrate/configurable/class-methods.rb', line 68

def nested(hash=nil, &block)
  nested = Class.new(Struct)
  nested.settings(hash || {})
  if block_given?
    nested.instance_eval(&block)
  end
  return nested
end

#nil_fields(*names) ⇒ Object Also known as: nil_field

Quick list of setting fields with a default value of nil. Useful especially with CascadingDefinition#resolve_configuration



79
80
81
82
83
84
# File 'lib/calibrate/configurable/class-methods.rb', line 79

def nil_fields(*names)
  names.each do |name|
    setting(name, nil)
  end
  self
end

#required_fields(*names) ⇒ Object Also known as: required_field

List fields with no default for with a value must be set before definition.



89
90
91
92
93
94
# File 'lib/calibrate/configurable/class-methods.rb', line 89

def required_fields(*names)
  names.each do |name|
    setting(name)
  end
  self
end

#runtime_required_fields(*names) ⇒ Object Also known as: runtime_required_field



121
122
123
124
125
126
# File 'lib/calibrate/configurable/class-methods.rb', line 121

def runtime_required_fields(*names)
  names.each do |name|
    runtime_setting(name)
  end
  self
end

#runtime_setting(name, default_value = RequiredField) ⇒ Object



129
130
131
# File 'lib/calibrate/configurable/class-methods.rb', line 129

def runtime_setting(name, default_value = RequiredField)
  setting(name, default_value).is(:runtime)
end

#set_defaults_on(instance) ⇒ Object



143
144
145
146
147
148
149
150
151
152
# File 'lib/calibrate/configurable/class-methods.rb', line 143

def set_defaults_on(instance)
  if Configurable > superclass
    superclass.set_defaults_on(instance)
  end
  default_values.each do |field|
    next unless field.is? :defaulting
    value = field.build_default_value
    instance.__send__(field.writer_method, value)
  end
end

#setting(name, default_value = RequiredField) ⇒ Object

Defines a setting on this class - much like a attr_accessible call, but allows for defaults and required settings



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/calibrate/configurable/class-methods.rb', line 99

def setting(name, default_value = RequiredField)
  name = name.to_sym
   =
    if default_value == RequiredField
      FieldMetadata.new(name, nil).is(:required).isnt(:defaulting)
    else
      FieldMetadata.new(name, default_value)
    end

  attr_writer(name)
  define_method(.reader_method) do
    .value_on(self)
  end

  if existing = default_values.find{|field| field.name == name} and existing.default_value != default_value
    source_line = caller.drop_while{|line| /#{__FILE__}/ =~ line}.first
      warn "Changing default value of #{self.name}##{name} from #{existing.default_value.inspect} to #{default_value.inspect} (at: #{source_line})"
  end
  default_values << 
  
end

#settings(hash) ⇒ Object Also known as: runtime_settings

Parameters:

  • hash (Hash)

    Pairs of name/value to be converted into setting/default



135
136
137
138
139
140
# File 'lib/calibrate/configurable/class-methods.rb', line 135

def settings(hash)
  hash.each_pair do |name, value|
    setting(name, value)
  end
  return self
end

#to_hash(obj) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/calibrate/configurable/class-methods.rb', line 174

def to_hash(obj)
  hash = if Configurable > superclass
           superclass.to_hash(obj)
         else
           {}
         end
  hash.merge( Hash[default_values.map{|field|
    begin
      value = obj.__send__(field.reader_method)
      value =
        case value
        when Configurable
          value.to_hash
        else
          value
        end
      [field.name, value]
    rescue NoMethodError
    end
  }])
end