Class: ConfigToolkit::RubyReader::Interpreter::ObjectProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/configtoolkit/rubyreader.rb

Overview

ObjectProxy instances use method_missing to build up configuration Hashes (returned by the Reader’s read method) from arbitrary parameter references in the Ruby configuration file. An instance maintains two Hashes. The first is the configuration hash that maps parameter names to parameter values and containing object names to Hashes. The second is the proxy hash that maps containing object names to ObjectProxy instances (and parameter names to the SimpleParam singleton marker).

For instance, if the configuration file has “config.age = 5”, age= will trigger a method_missing call that in turn will map :age to 5 in its configuration hash table (and also :age to SimpleParam in its proxy hash table if :age was encountered for the first time). A line like “config.first.age = 5”, will trigger a method_missing call to first. Assuming first does not exist already, a new ObjectProxy will be created for it (:first => new ObjectProxy in the proxy hash table and :first => {} in the configuration hash table) and returned; age then will work with the new ObjectProxy as described.

method_missing classifies references according to the following: 1.) Setter methods must be setting parameters. 2.) Getter methods must refer to a containing object if

the name never has been encountered before and, if it has,
to whatever it originally was resolved.

Thus, containing objects are referred to via getters and only can be referred to via getters. Parameters first must be referred to via a setter and then can be referred to via a getter or a setter (you can’t get the value of a parameter that hasn’t been set yet, after all). Getters for containing objects return ObjectProxy instances, so that they in turn can service member references (i.e, “config.first.second.age = 2” has config, first, and second returning ObjectProxy instances).

The configuration and proxy hashes have parallel structures, with the configuration hash mapping names to values and the proxy hash mapping names to containing object proxies.

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ ObjectProxy

Description:

This contructs a ObjectProxy instance to have empty configuration and proxy hashes.



118
119
120
121
122
# File 'lib/configtoolkit/rubyreader.rb', line 118

def initialize(name)
  @name = name
  @config_hash = {}
  @proxy_hash = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object

Description:

This method simulates methods in order to allow configuration files to reference arbitrary parameter and containing object names. When a configuration file contains “config.first.second.age = 2”, the references to first, second, and age are handled by this method.

Parameters:

method_name

The missing method

*args

The arguments to the missing method

Returns:

If a getter, then the ObjectProxy associated with the containing object or the parameter’s value. If a setter (which must act on a parameter), then the new value.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/configtoolkit/rubyreader.rb', line 158

def method_missing(method_name, *args)
  method_name_str = method_name.to_s()
  
  if((method_name_str.size() >= 2) && (method_name_str[0, 2] == "[]"))
    raise Error, "cannot index with array notation into #{@name}"
  elsif(method_name_str[-1,1] == "=")
    new_value = args[0]

    #
    # The interpreter more or less guarantees that args.size() == 1
    # for setter methods.
    #

    #
    # Get rid of the trailing '='
    #
    object_name = method_name_str[0, method_name_str.size() - 1].to_sym()
    proxy = @proxy_hash.fetch(object_name, nil)
    if(proxy == nil)
      #
      # A parameter value is being set for the first time, so
      # record the parameter name in the proxy hash
      #
      @proxy_hash[object_name] = SimpleParam.instance()
      return (@config_hash[object_name] = new_value)
    elsif(proxy.is_a?(SimpleParam))
      return (@config_hash[object_name] = new_value)
    else
      raise Error, "cannot assign to object #{@name}.#{object_name}"
    end
  elsif(args.size != 0)
    super.missing_method(method_name, *args)
  else
    object_name = method_name
    proxy = @proxy_hash.fetch(object_name, nil)

    if(proxy == nil)
      #
      # Since this is a getter and there is no record of the
      # name, the name must refer to a containing object.
      #
      proxy = @proxy_hash[object_name] = ObjectProxy.new("#{@name}.#{object_name}")
      @config_hash[object_name] = proxy.___config_hash___
      return proxy
    elsif(proxy.is_a?(ObjectProxy))
      return proxy
    else
      return @config_hash[object_name]
    end
  end
end

Instance Method Details

#___config_hash___Object

Description:

This is an accessor for the @config_hash member variable. It is surrounded by _ characters on each side in order to reduce the chance of any collision occurring with a name referenced in the configuration file (config_hash cannot be used as a parameter or containing object name).

Returns:



135
136
137
# File 'lib/configtoolkit/rubyreader.rb', line 135

def ___config_hash___
  return @config_hash
end