Mash allows you to create pseudo-objects that have method-like accessors for hash keys. This is useful for such implementations as an API-accessing library that wants to fake robust objects without the overhead of actually doing so. Think of it as OpenStruct with some additional goodies.
A Mash will look at the methods you pass it and perform operations based on the following rules:
No punctuation: Returns the value of the hash for that key, or nil if none exists.
Assignment (=): Sets the attribute of the given method name.
Existence (?): Returns true or false depending on whether that key has been set.
Bang (!): Forces the existence of this key, used for deep Mashes. Think of it as "touch" for mashes.
mash = Mash.new mash.name? # => false mash.name = "Bob" mash.name # => "Bob" mash.name? # => true
hash = {:a => {:b => 23, :d => {:e => "abc"}}, :f => [{:g => 44, :h => 29}, 12]} mash = Mash.new(hash) mash.a.b # => 23 mash.a.d.e # => "abc" mash.f.first.g # => 44 mash.f.last # => 12
mash = Mash.new mash.author # => nil mash.author! # => <Mash> mash = Mash.new mash.author!.name = "Michael Bleigh" mash.author # => <Mash name="Michael Bleigh">
If you pass in an existing hash, it will convert it to a Mash including recursively descending into arrays and hashes, converting them as well.
# File lib/mash.rb, line 49 def initialize(source_hash = nil) deep_update(source_hash) if source_hash super(nil) end
Retrieves an attribute set in the Mash. Will convert any key passed in to a string before retrieving.
# File lib/mash.rb, line 79 def [](key) key = convert_key(key) regular_reader(key) end
Performs a deep_update on a duplicate of the current mash.
# File lib/mash.rb, line 124 def deep_merge(other_hash) dup.deep_merge!(other_hash) end
Recursively merges this mash with the passed in hash, merging each hash in the hierarchy.
# File lib/mash.rb, line 130 def deep_update(other_hash) stringified_hash = other_hash.stringify_keys stringified_hash.each_pair do |k,v| k = convert_key(k) self[k] = self[k].to_mash if self[k].is_a?(Hash) unless self[k].is_a?(Mash) if self[k].is_a?(Hash) && stringified_hash[k].is_a?(Hash) self[k].deep_merge!(stringified_hash[k]) else self.send(k + "=", convert_value(stringified_hash[k])) end end end
Borrowed from Merb's Mash object.
key<Object> |
The default value for the mash. Defaults to nil. |
If key is a Symbol and it is a key in the mash, then the default value will be set to the value matching the key.
# File lib/mash.rb, line 66 def default(key = nil) if key.is_a?(Symbol) && key?(key) self[key] else super end end
Duplicates the current mash as a new mash.
# File lib/mash.rb, line 99 def dup Mash.new(self) end
This is the bang method reader, it will return a new Mash if there isn't a value already assigned to the key requested.
# File lib/mash.rb, line 93 def initializing_reader(key) return self[key] if key?(key) self[key] = Mash.new end
Prints out a pretty object-like string of the defined attributes.
# File lib/mash.rb, line 112 def inspect ret = "<#{self.class.to_s}" keys.sort.each do |key| ret << " #{key}=#{self[key].inspect}" end ret << ">" ret end
# File lib/mash.rb, line 106 def key?(key) picky_key?(convert_key(key)) end
Converts a mash back to a hash (with stringified keys)
# File lib/mash.rb, line 164 def to_hash Hash.new(default).merge(self) end
other_hash<Hash> |
A hash to update values in the mash with. Keys will be stringified and Hashes will be converted to Mashes. Returns
|
# File lib/mash.rb, line 151 def update(other_hash) other_hash.each_pair do |key, value| if respond_to?(convert_key(key) + "=") self.send(convert_key(key) + "=", convert_value(value)) else regular_writer(convert_key(key), convert_value(value)) end end self end
Generated with the Darkfish Rdoc Generator 2.