class Configurability::Config::Struct
Hash-wrapper that allows struct-like accessor calls on nested hashes.
Public Class Methods
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
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
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
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
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 the struct has having been modified since its creation.
# File lib/configurability/config.rb, line 393 def mark_dirty @dirty = true end
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
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
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 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
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
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
Protected Instance Methods
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 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 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
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