Class: Hashie::Mash

Inherits:
Hash show all
Includes:
PrettyInspect
Defined in:
lib/pancake/vendor/hashie/lib/hashie/mash.rb

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.author # => nil
mash.author! # => <Mash>

mash = Mash.new
mash.author!.name = "Michael Bleigh"
mash.author # => <Mash name="Michael Bleigh">

Instance Method Summary collapse

Methods included from PrettyInspect

#hashie_inspect, included

Methods inherited from Hash

#to_hash, #to_json

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.



51
52
53
54
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 51

def initialize(source_hash = nil, default = nil, &blk)
  deep_update(source_hash) if source_hash
  default ? super(default) : super(&blk)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &blk) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 115

def method_missing(method_name, *args, &blk)
  return self[method_name] if key?(method_name)
  match = method_name.to_s.match(/(.*?)([?=!]?)$/)
  case match[2]
  when "="
    self[match[1]] = args.first
  when "?"
    key?(match[1])
  when "!"
    initializing_reader(match[1])
  else
    default(method_name, *args, &blk)
  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.



67
68
69
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 67

def [](key)
  regular_reader(convert_key(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.



74
75
76
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 74

def []=(key,value) #:nodoc:
  regular_writer(convert_key(key), convert_value(value))
end

#deep_merge(other_hash) ⇒ Object

Performs a deep_update on a duplicate of the current mash.



98
99
100
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 98

def deep_merge(other_hash)
  dup.deep_merge!(other_hash)
end

#deep_update(other_hash) ⇒ Object Also known as: deep_merge!, update

Recursively merges this mash with the passed in hash, merging each hash in the hierarchy.



104
105
106
107
108
109
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 104

def deep_update(other_hash)
  other_hash.each_pair do |k,v|
    regular_writer(convert_key(k), convert_value(other_hash[k], true))
  end
  self
end

#dupObject

Duplicates the current mash as a new mash.



88
89
90
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 88

def dup
  Mash.new(self, self.default)
end

#idObject

:nodoc:



58
59
60
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 58

def id #:nodoc:
  key?("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.



80
81
82
83
84
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 80

def initializing_reader(key)
  ck = convert_key(key)
  regular_writer(ck, Hashie::Mash.new) unless key?(ck)
  regular_reader(ck)
end

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 92

def key?(key)
  super(convert_key(key))
end

#regular_dupObject



86
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 86

alias_method :regular_dup, :dup

#regular_readerObject



62
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 62

alias_method :regular_reader, :[]

#regular_writerObject



63
# File 'lib/pancake/vendor/hashie/lib/hashie/mash.rb', line 63

alias_method :regular_writer, :[]=