Class: Mash

Inherits:
Hash
  • Object
show all
Defined in:
lib/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">

Constant Summary collapse

VERSION =
'0.0.2'

Instance Method Summary collapse

Constructor Details

#initialize(source_hash = nil) ⇒ 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.



49
50
51
52
# File 'lib/mash.rb', line 49

def initialize(source_hash = nil)
  mash_a_hash(source_hash) if source_hash
  super(nil)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object

:nodoc:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mash.rb', line 82

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
    return self[match[1]] if key?(match[1])
    self[match[1]] = Mash.new
  elsif keys.include?(method_name.to_s)
    self[method_name]
  elsif match = method_name.to_s.match(/^([a-z][a-z0-9A-Z_]+)$/)
    nil
  else
    super
  end
end

Instance Method Details

#[](key) ⇒ Object

:nodoc:



58
59
60
61
62
# File 'lib/mash.rb', line 58

def [](key) #:nodoc:
  key = key.to_s
  return Mash.new unless key?(key)    
  super
end

#[]=(key, value) ⇒ Object

:nodoc:



64
65
66
67
# File 'lib/mash.rb', line 64

def []=(key,value) #:nodoc:
  key = key.to_s
  super
end

#idObject

:nodoc:



54
55
56
# File 'lib/mash.rb', line 54

def id #:nodoc:
  self["id"] ? self["id"] : super
end

#inspectObject Also known as: to_s

Prints out a pretty object-like string of the defined attributes.



71
72
73
74
75
76
77
78
# File 'lib/mash.rb', line 71

def inspect
  ret = "<#{self.class.to_s}"
  keys.sort.each do |key|
    ret << " #{key}=#{self[key].inspect}"
  end
  ret << ">"
  ret
end