Class: FunWith::Configurations::Config

Inherits:
Object
  • Object
show all
Includes:
ConfigOverriddenMethods
Defined in:
lib/fun_with/configurations/config.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ConfigOverriddenMethods

override_method

Constructor Details

#initialize(key_to_self = nil, parent = nil, &block) ⇒ Config



30
31
32
33
34
35
# File 'lib/fun_with/configurations/config.rb', line 30

def initialize( key_to_self = nil, parent = nil, &block )
  @key_to_self = key_to_self
  @parent      = parent
  @config_vars = {}
  self.instance_exec( &block ) if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/fun_with/configurations/config.rb', line 37

def method_missing( method, *args, &block )
  method = method.to_s.gsub( /=$/, '' ).to_sym
  
  if block_given?
    self[method] = Config.new(method, self) unless self[method].is_a?(Config)
    self[method].instance_exec( &block )
  elsif args.length == 1
    self[method] = args.first
  elsif args.length > 1
    self[method] = args
  else
    self[method]   
  end
end

Class Method Details

.from_hash(hash) ⇒ Object



145
146
147
148
149
150
151
152
# File 'lib/fun_with/configurations/config.rb', line 145

def self.from_hash( hash )
  (config = self.new).tap do
    for k, v in hash
      config.send( k, v.is_a?( Hash ) ? self.from_hash( v ) : v )
    end
  end
  config
end

.fwc_overridden_methodsObject



154
155
156
# File 'lib/fun_with/configurations/config.rb', line 154

def self.fwc_overridden_methods
  ConfigOverriddenMethods.instance_methods.grep( /[^=]$/ )
end

.key_check(sym) ⇒ Object

Raises:



87
88
89
90
91
92
# File 'lib/fun_with/configurations/config.rb', line 87

def self.key_check( sym )
  @reserved_symbols ||= Config.instance_methods - self.fwc_overridden_methods
  
  raise KeyError.new("#{sym} is not a symbol") unless sym.is_a?(Symbol)
  raise KeyError.new("#{sym} is reserved for use by Hash") if @reserved_symbols.include?( sym )
end

Instance Method Details

#[](sym) ⇒ Object



52
53
54
55
56
# File 'lib/fun_with/configurations/config.rb', line 52

def []( sym )
  sym = sym.to_sym if sym.is_a?(String)
  self.class.key_check( sym )
  @config_vars[ sym ]
end

#[]=(sym, val) ⇒ Object



58
59
60
61
62
# File 'lib/fun_with/configurations/config.rb', line 58

def []=( sym, val )
  sym = sym.to_sym if sym.is_a?(String)
  self.class.key_check( sym )
  @config_vars[ sym ] = val
end

#each(*args, &block) ⇒ Object



122
123
124
# File 'lib/fun_with/configurations/config.rb', line 122

def each( *args, &block )
  @config_vars.each( *args, &block )
end

#fwc_overridden_methodsObject



158
159
160
# File 'lib/fun_with/configurations/config.rb', line 158

def fwc_overridden_methods
  self.class.fwc_overridden_methods
end

#promote_configuration(*keys) ⇒ Object

Say you had a configuration that had multiple entries, and you wanted to select from among them at runtime. Example: config:

important_folder:
  development: "/this/directory",
  test:        "/that/directory",
  production:  "~/another/directory"

You could do config.important_folder every time you want to access that setting. Or you can do config.important_folder.promote_configuration(:development) and have the development subconfiguration replace the important_folder: configuration

You can promote a sub-sub-sub-config by sending an array of symbols. But I hope it never comes to that.



78
79
80
81
82
83
84
85
# File 'lib/fun_with/configurations/config.rb', line 78

def promote_configuration( *keys )
  replace_with = self.try.config_method_chain_result( keys )
  if replace_with.success?
    @parent[@key_to_self] = replace_with.config
  else
    raise ChainError.new( "config failed to promote_configuration #{keys.inspect}" )
  end
end

#to_hashObject



137
138
139
140
141
142
143
# File 'lib/fun_with/configurations/config.rb', line 137

def to_hash
  (hash = {}).tap do
    for k, v in @config_vars
      hash[k] = v.is_a?(Config) ? v.to_hash : v
    end
  end
end

#to_ruby_code(indent = 0) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/fun_with/configurations/config.rb', line 102

def to_ruby_code( indent = 0 )
  (code = "").tap do
    if indent == 0
      code << "FunWith::Configurations::Config.new do\n"
      code << self.to_ruby_code( 2 )
      code << "end\n"
    else
      for k, v in @config_vars
        if v.is_a?( Config )
          code << (" " * indent) + "#{k} do\n"
          code << v.to_ruby_code( indent + 2 )
          code << (" " * indent) + "end\n"
        else
          code << (" " * indent) + "#{k} #{v.inspect}\n"
        end
      end
    end
  end
end

#to_s(style = :hash) ⇒ Object



126
127
128
129
130
131
132
133
134
135
# File 'lib/fun_with/configurations/config.rb', line 126

def to_s( style = :hash )
  case style
  when :hash
    self.to_hash.inspect
  when :ruby
    self.to_ruby_code
  else
    super
  end
end

#try(*keys) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/fun_with/configurations/config.rb', line 94

def try( *keys )
  (t = TryObject.new( self )).tap do
    for key in keys
      t[key]
    end
  end
end