Class: Hashie::Mash
Overview
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.
Basic Example
mash = Mash.new
mash.name? # => false
mash.name = "Bob"
mash.name # => "Bob"
mash.name? # => true
Hash Conversion Example
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
Bang Example
mash = Mash.new
mash. # => nil
mash. # => <Mash>
mash = Mash.new
mash..name = "Michael Bleigh"
mash. # => <Mash name="Michael Bleigh">
Instance Method Summary collapse
-
#[](key) ⇒ Object
Retrieves an attribute set in the Mash.
-
#[]=(key, value) ⇒ Object
Sets an attribute in the Mash.
-
#deep_merge(other_hash) ⇒ Object
Performs a deep_update on a duplicate of the current mash.
-
#deep_update(other_hash) ⇒ Object
(also: #deep_merge!)
Recursively merges this mash with the passed in hash, merging each hash in the hierarchy.
-
#default(key = nil) ⇒ Object
Borrowed from Merb’s Mash object.
-
#dup ⇒ Object
Duplicates the current mash as a new mash.
-
#id ⇒ Object
:nodoc:.
-
#initialize(source_hash = nil, default = nil, &blk) ⇒ Mash
constructor
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.
-
#initializing_reader(key) ⇒ Object
This is the bang method reader, it will return a new Mash if there isn’t a value already assigned to the key requested.
-
#inspect ⇒ Object
(also: #to_s)
Prints out a pretty object-like string of the defined attributes.
- #key?(key) ⇒ Boolean
-
#method_missing(method_name, *args) ⇒ Object
:nodoc:.
- #picky_key? ⇒ Object
- #regular_dup ⇒ Object
- #regular_inspect ⇒ Object
- #regular_reader ⇒ Object
- #regular_writer ⇒ Object
-
#to_hash ⇒ Object
Converts a mash back to a hash (with stringified keys).
-
#update(other_hash) ⇒ Object
(also: #merge!)
Parameters other_hash<Hash>:: A hash to update values in the mash with.
Methods included from HashExtensions
#hashie_stringify_keys, #hashie_stringify_keys!, included, #to_mash
Constructor Details
#initialize(source_hash = nil, default = nil, &blk) ⇒ Mash
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.
48 49 50 51 52 |
# File 'lib/hashie/mash.rb', line 48 def initialize(source_hash = nil, default = nil, &blk) deep_update(source_hash) if source_hash super default if default super &blk if blk end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args) ⇒ Object
:nodoc:
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/hashie/mash.rb', line 174 def method_missing(method_name, *args) #:nodoc: if (match = method_name.to_s.match(/(.*)=$/)) && args.size == 1 self[match[1]] = args.first elsif (match = method_name.to_s.match(/(.*)\?$/)) && args.size == 0 key?(match[1]) elsif (match = method_name.to_s.match(/(.*)!$/)) && args.size == 0 initializing_reader(match[1]) elsif key?(method_name) self[method_name] elsif match = method_name.to_s.match(/^([a-z][a-z0-9A-Z_]+)$/) default(method_name) else super end end |
Instance Method Details
#[](key) ⇒ Object
Retrieves an attribute set in the Mash. Will convert any key passed in to a string before retrieving.
81 82 83 84 |
# File 'lib/hashie/mash.rb', line 81 def [](key) key = convert_key(key) regular_reader(key) end |
#[]=(key, value) ⇒ Object
Sets an attribute in the Mash. Key will be converted to a string before it is set, and Hashes will be converted into Mashes for nesting purposes.
89 90 91 92 |
# File 'lib/hashie/mash.rb', line 89 def []=(key,value) #:nodoc: key = convert_key(key) regular_writer(key, convert_value(value)) end |
#deep_merge(other_hash) ⇒ Object
Performs a deep_update on a duplicate of the current mash.
127 128 129 |
# File 'lib/hashie/mash.rb', line 127 def deep_merge(other_hash) dup.deep_merge!(other_hash) end |
#deep_update(other_hash) ⇒ Object Also known as: deep_merge!
Recursively merges this mash with the passed in hash, merging each hash in the hierarchy.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/hashie/mash.rb', line 133 def deep_update(other_hash) other_hash = Hashie::Hash[other_hash].stringify_keys! other_hash.each_pair do |k,v| k = convert_key(k) self[k] = Hashie::Mash.new(self[k]).to_mash if self[k].is_a?(Hash) unless self[k].is_a?(Hashie::Mash) if self[k].is_a?(Hashie::Mash) && other_hash[k].is_a?(Hash) self[k] = self[k].deep_merge(other_hash[k]) else self[k] = convert_value(other_hash[k],true) end end self end |
#default(key = nil) ⇒ Object
Borrowed from Merb’s Mash object.
Parameters
- key<Object>
-
The default value for the mash. Defaults to nil.
Alternatives
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.
68 69 70 71 72 73 74 |
# File 'lib/hashie/mash.rb', line 68 def default(key = nil) if key.is_a?(Symbol) && key?(key.to_s) self[key] else key ? super : super() end end |
#dup ⇒ Object
Duplicates the current mash as a new mash.
103 104 105 |
# File 'lib/hashie/mash.rb', line 103 def dup Mash.new(self, self.default) end |
#id ⇒ Object
:nodoc:
56 57 58 |
# File 'lib/hashie/mash.rb', line 56 def id #:nodoc: self["id"] ? self["id"] : super end |
#initializing_reader(key) ⇒ Object
This is the bang method reader, it will return a new Mash if there isn’t a value already assigned to the key requested.
96 97 98 99 |
# File 'lib/hashie/mash.rb', line 96 def initializing_reader(key) self[key] = Hashie::Mash.new unless key?(key) self[key] end |
#inspect ⇒ Object Also known as: to_s
Prints out a pretty object-like string of the defined attributes.
115 116 117 118 119 120 121 122 |
# File 'lib/hashie/mash.rb', line 115 def inspect ret = "<#{self.class.to_s}" keys.sort.each do |key| ret << " #{key}=#{self[key].inspect}" end ret << ">" ret end |
#key?(key) ⇒ Boolean
108 109 110 |
# File 'lib/hashie/mash.rb', line 108 def key?(key) picky_key?(convert_key(key)) end |
#picky_key? ⇒ Object
107 |
# File 'lib/hashie/mash.rb', line 107 alias_method :picky_key?, :key? |
#regular_dup ⇒ Object
101 |
# File 'lib/hashie/mash.rb', line 101 alias_method :regular_dup, :dup |
#regular_inspect ⇒ Object
112 |
# File 'lib/hashie/mash.rb', line 112 alias_method :regular_inspect, :inspect |
#regular_reader ⇒ Object
76 |
# File 'lib/hashie/mash.rb', line 76 alias_method :regular_reader, :[] |
#regular_writer ⇒ Object
77 |
# File 'lib/hashie/mash.rb', line 77 alias_method :regular_writer, :[]= |
#to_hash ⇒ Object
Converts a mash back to a hash (with stringified keys)
170 171 172 |
# File 'lib/hashie/mash.rb', line 170 def to_hash Hash.new(default).merge(self) end |
#update(other_hash) ⇒ Object Also known as: merge!
Parameters
- other_hash<Hash>
-
A hash to update values in the mash with. Keys will be stringified and Hashes will be converted to Mashes.
Returns
- Mash
-
The updated mash.
157 158 159 160 161 162 163 164 165 166 |
# File 'lib/hashie/mash.rb', line 157 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 |