hashie 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -1
- data/VERSION +1 -1
- data/hashie.gemspec +2 -2
- data/lib/hashie/dash.rb +15 -16
- data/lib/hashie/hash_extensions.rb +9 -7
- data/lib/hashie/mash.rb +44 -90
- metadata +2 -2
data/.gitignore
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/hashie.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hashie}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Bleigh"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-13}
|
13
13
|
s.description = %q{Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).}
|
14
14
|
s.email = %q{michael@intridea.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/hashie/dash.rb
CHANGED
@@ -7,7 +7,7 @@ module Hashie
|
|
7
7
|
# optional defaults) and only those keys may be set or read.
|
8
8
|
#
|
9
9
|
# Dashes are useful when you need to create a very simple
|
10
|
-
# lightweight data object that needs even fewer options and
|
10
|
+
# lightweight data object that needs even fewer options and
|
11
11
|
# resources than something like a DataMapper resource.
|
12
12
|
#
|
13
13
|
# It is preferrable to a Struct because of the in-class
|
@@ -15,67 +15,66 @@ module Hashie
|
|
15
15
|
class Dash < Hashie::Hash
|
16
16
|
include Hashie::PrettyInspect
|
17
17
|
alias_method :to_s, :inspect
|
18
|
-
|
18
|
+
|
19
19
|
# Defines a property on the Dash. Options are
|
20
20
|
# as follows:
|
21
|
-
#
|
22
|
-
# * <tt>:default</tt> - Specify a default value for this property,
|
21
|
+
#
|
22
|
+
# * <tt>:default</tt> - Specify a default value for this property,
|
23
23
|
# to be returned before a value is set on the property in a new
|
24
24
|
# Dash.
|
25
25
|
#
|
26
26
|
def self.property(property_name, options = {})
|
27
27
|
property_name = property_name.to_sym
|
28
|
-
|
28
|
+
|
29
29
|
(@properties ||= []) << property_name
|
30
30
|
(@defaults ||= {})[property_name] = options.delete(:default)
|
31
|
-
|
31
|
+
|
32
32
|
class_eval <<-RUBY
|
33
33
|
def #{property_name}
|
34
34
|
self[:#{property_name}]
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def #{property_name}=(val)
|
38
38
|
self[:#{property_name}] = val
|
39
39
|
end
|
40
40
|
RUBY
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
# Get a String array of the currently defined
|
44
44
|
# properties on this Dash.
|
45
45
|
def self.properties
|
46
46
|
@properties.collect{|p| p.to_s}
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
# Check to see if the specified property has already been
|
50
50
|
# defined.
|
51
51
|
def self.property?(prop)
|
52
52
|
properties.include?(prop.to_s)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
# The default values that have been set for this Dash
|
56
56
|
def self.defaults
|
57
57
|
@defaults
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# You may initialize a Dash with an attributes hash
|
61
61
|
# just like you would many other kinds of data objects.
|
62
62
|
def initialize(attributes = {})
|
63
63
|
self.class.properties.each do |prop|
|
64
|
-
puts "#{prop}="
|
65
64
|
self.send("#{prop}=", self.class.defaults[prop.to_sym])
|
66
65
|
end
|
67
|
-
|
66
|
+
|
68
67
|
attributes.each_pair do |att, value|
|
69
68
|
self.send("#{att}=", value)
|
70
69
|
end
|
71
70
|
end
|
72
|
-
|
71
|
+
|
73
72
|
# Retrieve a value from the Dash (will return the
|
74
73
|
# property's default value if it hasn't been set).
|
75
74
|
def [](property_name)
|
76
75
|
super(property_name.to_sym)
|
77
76
|
end
|
78
|
-
|
77
|
+
|
79
78
|
# Set a value on the Dash in a Hash-like way. Only works
|
80
79
|
# on pre-existing properties.
|
81
80
|
def []=(property, value)
|
@@ -86,4 +85,4 @@ module Hashie
|
|
86
85
|
end
|
87
86
|
end
|
88
87
|
end
|
89
|
-
end
|
88
|
+
end
|
@@ -7,34 +7,36 @@ module Hashie
|
|
7
7
|
base.send :alias_method, hashie_method, "hashie_#{hashie_method}" unless base.instance_methods.include?(hashie_method)
|
8
8
|
end
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
# Destructively convert all of the keys of a Hash
|
12
12
|
# to their string representations.
|
13
13
|
def hashie_stringify_keys!
|
14
14
|
self.keys.each do |k|
|
15
|
-
|
15
|
+
unless String === k
|
16
|
+
self[k.to_s] = self.delete(k)
|
17
|
+
end
|
16
18
|
end
|
17
19
|
self
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
# Convert all of the keys of a Hash
|
21
23
|
# to their string representations.
|
22
24
|
def hashie_stringify_keys
|
23
25
|
self.dup.stringify_keys!
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
# Convert this hash into a Mash
|
27
29
|
def to_mash
|
28
30
|
Hashie::Mash.new(self)
|
29
31
|
end
|
30
32
|
end
|
31
|
-
|
33
|
+
|
32
34
|
module PrettyInspect
|
33
35
|
def self.included(base)
|
34
36
|
base.send :alias_method, :hash_inspect, :inspect
|
35
37
|
base.send :alias_method, :inspect, :hashie_inspect
|
36
38
|
end
|
37
|
-
|
39
|
+
|
38
40
|
def hashie_inspect
|
39
41
|
ret = "<##{self.class.to_s}"
|
40
42
|
keys.sort.each do |key|
|
@@ -44,4 +46,4 @@ module Hashie
|
|
44
46
|
ret
|
45
47
|
end
|
46
48
|
end
|
47
|
-
end
|
49
|
+
end
|
data/lib/hashie/mash.rb
CHANGED
@@ -7,14 +7,14 @@ module Hashie
|
|
7
7
|
#
|
8
8
|
# A Mash will look at the methods you pass it and perform operations
|
9
9
|
# based on the following rules:
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# * No punctuation: Returns the value of the hash for that key, or nil if none exists.
|
12
12
|
# * Assignment (<tt>=</tt>): Sets the attribute of the given method name.
|
13
13
|
# * Existence (<tt>?</tt>): Returns true or false depending on whether that key has been set.
|
14
14
|
# * Bang (<tt>!</tt>): Forces the existence of this key, used for deep Mashes. Think of it as "touch" for mashes.
|
15
15
|
#
|
16
16
|
# == Basic Example
|
17
|
-
#
|
17
|
+
#
|
18
18
|
# mash = Mash.new
|
19
19
|
# mash.name? # => false
|
20
20
|
# mash.name = "Bob"
|
@@ -22,7 +22,7 @@ module Hashie
|
|
22
22
|
# mash.name? # => true
|
23
23
|
#
|
24
24
|
# == Hash Conversion Example
|
25
|
-
#
|
25
|
+
#
|
26
26
|
# hash = {:a => {:b => 23, :d => {:e => "abc"}}, :f => [{:g => 44, :h => 29}, 12]}
|
27
27
|
# mash = Mash.new(hash)
|
28
28
|
# mash.a.b # => 23
|
@@ -35,7 +35,7 @@ module Hashie
|
|
35
35
|
# mash = Mash.new
|
36
36
|
# mash.author # => nil
|
37
37
|
# mash.author! # => <Mash>
|
38
|
-
#
|
38
|
+
#
|
39
39
|
# mash = Mash.new
|
40
40
|
# mash.author!.name = "Michael Bleigh"
|
41
41
|
# mash.author # => <Mash name="Michael Bleigh">
|
@@ -43,146 +43,100 @@ module Hashie
|
|
43
43
|
class Mash < Hashie::Hash
|
44
44
|
include Hashie::PrettyInspect
|
45
45
|
alias_method :to_s, :inspect
|
46
|
-
|
46
|
+
|
47
47
|
# If you pass in an existing hash, it will
|
48
48
|
# convert it to a Mash including recursively
|
49
49
|
# descending into arrays and hashes, converting
|
50
50
|
# them as well.
|
51
51
|
def initialize(source_hash = nil, default = nil, &blk)
|
52
52
|
deep_update(source_hash) if source_hash
|
53
|
-
super
|
54
|
-
super &blk if blk
|
53
|
+
default ? super(default) : super(&blk)
|
55
54
|
end
|
56
|
-
|
55
|
+
|
57
56
|
class << self; alias [] new; end
|
58
57
|
|
59
58
|
def id #:nodoc:
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
# Borrowed from Merb's Mash object.
|
64
|
-
#
|
65
|
-
# ==== Parameters
|
66
|
-
# key<Object>:: The default value for the mash. Defaults to nil.
|
67
|
-
#
|
68
|
-
# ==== Alternatives
|
69
|
-
# If key is a Symbol and it is a key in the mash, then the default value will
|
70
|
-
# be set to the value matching the key.
|
71
|
-
def default(key = nil)
|
72
|
-
if key.is_a?(Symbol) && key?(key.to_s)
|
73
|
-
self[key]
|
74
|
-
else
|
75
|
-
key ? super : super()
|
76
|
-
end
|
59
|
+
key?("id") ? self["id"] : super
|
77
60
|
end
|
78
|
-
|
61
|
+
|
79
62
|
alias_method :regular_reader, :[]
|
80
63
|
alias_method :regular_writer, :[]=
|
81
|
-
|
64
|
+
|
82
65
|
# Retrieves an attribute set in the Mash. Will convert
|
83
66
|
# any key passed in to a string before retrieving.
|
84
67
|
def [](key)
|
85
|
-
|
86
|
-
regular_reader(key)
|
68
|
+
regular_reader(convert_key(key))
|
87
69
|
end
|
88
|
-
|
70
|
+
|
89
71
|
# Sets an attribute in the Mash. Key will be converted to
|
90
72
|
# a string before it is set, and Hashes will be converted
|
91
73
|
# into Mashes for nesting purposes.
|
92
74
|
def []=(key,value) #:nodoc:
|
93
|
-
|
94
|
-
regular_writer(key, convert_value(value))
|
75
|
+
regular_writer(convert_key(key), convert_value(value))
|
95
76
|
end
|
96
|
-
|
77
|
+
|
97
78
|
# This is the bang method reader, it will return a new Mash
|
98
79
|
# if there isn't a value already assigned to the key requested.
|
99
80
|
def initializing_reader(key)
|
100
|
-
|
101
|
-
|
81
|
+
ck = convert_key(key)
|
82
|
+
regular_writer(ck, Hashie::Mash.new) unless key?(ck)
|
83
|
+
regular_reader(ck)
|
102
84
|
end
|
103
|
-
|
104
|
-
alias_method :regular_dup, :dup
|
85
|
+
|
86
|
+
alias_method :regular_dup, :dup
|
105
87
|
# Duplicates the current mash as a new mash.
|
106
88
|
def dup
|
107
89
|
Mash.new(self, self.default)
|
108
90
|
end
|
109
|
-
|
110
|
-
alias_method :picky_key?, :key?
|
91
|
+
|
111
92
|
def key?(key)
|
112
|
-
|
93
|
+
super(convert_key(key))
|
113
94
|
end
|
114
|
-
|
95
|
+
|
115
96
|
# Performs a deep_update on a duplicate of the
|
116
97
|
# current mash.
|
117
98
|
def deep_merge(other_hash)
|
118
99
|
dup.deep_merge!(other_hash)
|
119
100
|
end
|
120
|
-
|
101
|
+
|
121
102
|
# Recursively merges this mash with the passed
|
122
103
|
# in hash, merging each hash in the hierarchy.
|
123
104
|
def deep_update(other_hash)
|
124
|
-
other_hash = Hashie::Hash[other_hash].stringify_keys!
|
125
|
-
|
126
105
|
other_hash.each_pair do |k,v|
|
127
|
-
k
|
128
|
-
self[k] = Hashie::Mash.new(self[k]).to_mash if self[k].is_a?(Hash) unless self[k].is_a?(Hashie::Mash)
|
129
|
-
if self[k].is_a?(Hashie::Mash) && other_hash[k].is_a?(Hash)
|
130
|
-
self[k] = self[k].deep_merge(other_hash[k])
|
131
|
-
else
|
132
|
-
self[k] = convert_value(other_hash[k],true)
|
133
|
-
end
|
106
|
+
regular_writer(convert_key(k), convert_value(other_hash[k], true))
|
134
107
|
end
|
135
|
-
|
136
108
|
self
|
137
109
|
end
|
138
110
|
alias_method :deep_merge!, :deep_update
|
139
|
-
|
140
|
-
# ==== Parameters
|
141
|
-
# other_hash<Hash>::
|
142
|
-
# A hash to update values in the mash with. Keys will be
|
143
|
-
# stringified and Hashes will be converted to Mashes.
|
144
|
-
#
|
145
|
-
# ==== Returns
|
146
|
-
# Mash:: The updated mash.
|
147
|
-
def update(other_hash)
|
148
|
-
other_hash.each_pair do |key, value|
|
149
|
-
if respond_to?(convert_key(key) + "=")
|
150
|
-
self.send(convert_key(key) + "=", convert_value(value))
|
151
|
-
else
|
152
|
-
regular_writer(convert_key(key), convert_value(value))
|
153
|
-
end
|
154
|
-
end
|
155
|
-
self
|
156
|
-
end
|
111
|
+
alias_method :update, :deep_update
|
157
112
|
alias_method :merge!, :update
|
158
|
-
|
113
|
+
|
159
114
|
# Converts a mash back to a hash (with stringified keys)
|
160
115
|
def to_hash
|
161
116
|
Hash.new(default).merge(self)
|
162
117
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
118
|
+
|
119
|
+
def method_missing(method_name, *args)
|
120
|
+
return self[method_name] if key?(method_name)
|
121
|
+
match = method_name.to_s.match(/(.*?)([?=!]?)$/)
|
122
|
+
case match[2]
|
123
|
+
when "="
|
124
|
+
self[match[1]] = args.first
|
125
|
+
when "?"
|
126
|
+
key?(match[1])
|
127
|
+
when "!"
|
128
|
+
initializing_reader(match[1])
|
129
|
+
else
|
130
|
+
default(method_name)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
180
134
|
protected
|
181
|
-
|
135
|
+
|
182
136
|
def convert_key(key) #:nodoc:
|
183
137
|
key.to_s
|
184
138
|
end
|
185
|
-
|
139
|
+
|
186
140
|
def convert_value(val, duping=false) #:nodoc:
|
187
141
|
case val
|
188
142
|
when ::Hash
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-13 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|