Configurability::Config::

Struct class

Hash-wrapper that allows struct-like accessor calls on nested hashes.

Public Class Methods

new( hash=nil )

Create a new ConfigStruct using the values from the given hash if specified.

# File lib/configurability/config.rb, line 353
def initialize( hash=nil )
        hash ||= {}
        @hash = symbolify_keys( hash )
        @dirty = false
end

Public Instance Methods

[]( key )

Return the value associated with the specified key, or another Configurability::Config::ConfigStruct if key is a section name.

# File lib/configurability/config.rb, line 374
def []( key )
        key = key.to_sym if key.respond_to?( :to_sym )

        # Convert Hashes to Struct on the fly for subsections
        @hash[ key ] = self.class.new( @hash[key] ) if @hash[ key ].is_a?( Hash )

        return @hash[ key ]
end
[]=( key, value )

Set the value associated with the specified key to value.

# File lib/configurability/config.rb, line 385
def []=( key, value )
        key = key.to_sym
        self.mark_dirty if @hash[ key ] != value
        @hash[ key ] = value
end
dirty?()

Returns true if the ConfigStruct or any of its sub-structs have changed since it was created.

# File lib/configurability/config.rb, line 400
def dirty?
        return true if @dirty
        return true if @hash.values.find do |obj|
                obj.respond_to?( :dirty? ) && obj.dirty?
        end
end
has_member?( name )
Alias for: member?
inspect()

Return a human-readable representation of the Struct suitable for debugging.

# File lib/configurability/config.rb, line 491
def inspect
        return "#<%s:%0x16 %p>" % [
                self.class.name,
                self.object_id * 2,
                @hash,
        ]
end
mark_dirty()

Mark the struct has having been modified since its creation.

# File lib/configurability/config.rb, line 393
def mark_dirty
        @dirty = true
end
member?( name )

Returns true if the given name is the name of a member of the receiver.

# File lib/configurability/config.rb, line 447
def member?( name )
        name = name.to_sym if name.respond_to?( :to_sym )
        return @hash.key?( name )
end
Also aliased as: has_member?
members()

Returns an Array of Symbols, one for each of the struct’s members.

# File lib/configurability/config.rb, line 440
def members
        return @hash.keys
end
merge( other )

Return a new Configurability::Config::Struct which is the result of merging the receiver with the given other object (a Hash or another Configurability::Config::Struct).

# File lib/configurability/config.rb, line 485
def merge( other )
        self.dup.merge!( other )
end
merge!( other )

Merge the specified other object with this config struct. The other object can be either a Hash, another Configurability::Config::Struct, or an Configurability::Config.

# File lib/configurability/config.rb, line 457
def merge!( other )
        mergefunc = Configurability::Config.method( :merge_complex_hashes )

        case other
        when Hash
                @hash = self.to_h.merge( other, &mergefunc )

        when Configurability::Config::Struct
                @hash = self.to_h.merge( other.to_h, &mergefunc )

        when Configurability::Config
                @hash = self.to_h.merge( other.struct.to_h, &mergefunc )

        else
                raise TypeError,
                        "Don't know how to merge with a %p" % other.class
        end

        # :TODO: Actually check to see if anything has changed?
        @dirty = true

        return self
end
respond_to?( sym, priv=false )

Return true if the receiver responds to the given method. Overridden to grok autoloaded methods.

# File lib/configurability/config.rb, line 432
def respond_to?( sym, priv=false )
        key = sym.to_s.sub( /(=|\?)$/, '' ).to_sym
        return true if @hash.key?( key )
        super
end
to_h()
Alias for: to_hash
to_hash()

Return the receiver’s values as a (possibly multi-dimensional) Hash with String keys.

# File lib/configurability/config.rb, line 410
def to_hash
        rhash = {}
        @hash.each {|k,v|
                case v
                when Configurability::Config::Struct
                        rhash[k] = v.to_h
                when NilClass, FalseClass, TrueClass, Numeric
                        # No-op (can't dup)
                        rhash[k] = v
                when Symbol
                        rhash[k] = v.to_s
                else
                        rhash[k] = v.dup
                end
        }
        return rhash
end
Also aliased as: to_h

Protected Instance Methods

create_member_predicate( key )

Create a predicate method for the specified key and return it.

# File lib/configurability/config.rb, line 531
def create_member_predicate( key )
        return lambda { self.member?( key ) && self[key] ? true : false }
end
create_member_reader( key )

Create a reader method for the specified key and return it.

# File lib/configurability/config.rb, line 525
def create_member_reader( key )
        return lambda { self[key] }
end
create_member_writer( key )

Create a writer method for the specified key and return it.

# File lib/configurability/config.rb, line 537
def create_member_writer( key )
        return lambda {|val| self[key] = val }
end
method_missing( sym, *args )

Handle calls to key-methods

# File lib/configurability/config.rb, line 505
def method_missing( sym, *args )
        key = sym.to_s.sub( /(=|\?)$/, '' ).to_sym

        # Create new methods for this key
        reader    = self.create_member_reader( key )
        writer    = self.create_member_writer( key )
        predicate = self.create_member_predicate( key )

        # ...and install them
        self.class.send( :define_method, key, &reader )
        self.class.send( :define_method, "#{key}=", &writer )
        self.class.send( :define_method, "#{key}?", &predicate )

        # Now jump to the requested method in a way that won't come back through
        # the proxy method if something didn't get defined
        self.method( sym ).call( *args )
end