Module: Mattock::Configurable::ClassMethods

Included in:
Mattock::Configurable
Defined in:
lib/mattock/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/mattock/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/mattock/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/mattock/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/mattock/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

#included(mod) ⇒ Object



201
202
203
# File 'lib/mattock/configurable/class-methods.rb', line 201

def included(mod)
  mod.extend ClassMethods
end

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



28
29
30
31
32
33
# File 'lib/mattock/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



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/mattock/configurable/class-methods.rb', line 158

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/mattock/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 Mattock::CascadingDefinition#resolve_configuration



79
80
81
82
83
84
# File 'lib/mattock/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/mattock/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/mattock/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/mattock/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
153
154
155
156
# File 'lib/mattock/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.default_value
    if Module === value and Configurable > value
      value = value.new
      value.class.set_defaults_on(value)
    end
    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/mattock/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 = .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/mattock/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



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/mattock/configurable/class-methods.rb', line 178

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