hashlib 0.0.25 → 0.0.30

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.
Files changed (2) hide show
  1. data/lib/hashlib.rb +97 -99
  2. metadata +2 -2
data/lib/hashlib.rb CHANGED
@@ -21,89 +21,94 @@ class Hash
21
21
  end
22
22
 
23
23
  def rget(path, default=nil)
24
- rv = self
24
+ path = path.split('.') if path.is_a?(String)
25
+ return default if path.nil? or path.empty?
25
26
 
26
- # make path an array if not already
27
- if not path.is_a?(Array)
28
- path = path.to_s.split('.')
29
- end
27
+ # arrayify all paths
28
+ path = [*path]
29
+
30
+ root = self.stringify_keys()
31
+ key = path.first.to_s
32
+ rest = path[1..-1]
30
33
 
31
- # stringify path components
32
- path.collect!{|i| i.to_s }
33
-
34
- # step through path components...
35
- path.each_index do |i|
36
- # hashes: if the current path component is in the hash, set the pointer
37
- # and move on to the next path component
38
- # otherwise return default value
39
- #
40
- if rv.is_a?(Hash)
41
- # attempt lookup by string
42
- if rv.keys.include?(path[i])
43
- rv = rv[path[i]]
44
- next
45
-
46
- # attempt lookup by symbol
47
- elsif (path[i].to_sym rescue nil).is_a?(Symbol) and rv.keys.include?(path[i].to_sym)
48
- rv = rv[path[i].to_sym]
49
- next
50
-
51
- # you fail it
34
+ if root.has_key?(key)
35
+ if root[key].is_a?(Hash)
36
+ if rest.empty?
37
+ return root[key]
52
38
  else
53
- return default
39
+ return root[key].rget(rest, default)
40
+ end
41
+ elsif root[key].is_a?(Array) and root[key].first.is_a?(Hash)
42
+ if rest.empty?
43
+ return root[key]
44
+ else
45
+ return root[key].collect{|v|
46
+ v.rget(rest, default)
47
+ }.flatten
54
48
  end
55
-
56
- # arrays: flatten into one array, iterate over it. for each element:
57
- # if it is a hash, recurse into it from the next path component
58
- # otherwise return it
59
- # the resulant pointer should be fully populated from this point down
60
- #
61
- elsif rv.is_a?(Array)
62
- rv = (rv.flatten.collect do |j|
63
- if j.is_a?(Hash)
64
- j.get(path[(i)..-1], default)
65
- else
66
- j
67
- end
68
- end).compact
69
-
70
- next
71
-
72
- # scalars: if we're still in this loop and trying to look for a path component
73
- # inside of a scalar value, then that won't exist and we just return default
74
49
  else
75
- return default
50
+ return root[key]
76
51
  end
52
+ else
53
+ return default
77
54
  end
55
+ end
78
56
 
79
- return default if rv.nil? or (rv.is_a?(Array) and rv.flatten.compact.empty?)
80
57
 
81
- # good job! you made it here!
82
- return rv
83
- end
58
+ def rset(path, value, options={})
59
+ path = path.split('.') if path.is_a?(String)
60
+ return nil if path.nil? or path.empty?
84
61
 
85
- def rset(path, value)
86
- if not path.is_a?(Array)
87
- path = path.to_s.strip.split(/[\/\.]/)
88
- end
89
- root = self
62
+ # arrayify all paths
63
+ path = [*path]
90
64
 
91
- path[0..-2].each do |p|
92
- root[p.to_s] = {} unless root[p.to_s].is_a?(Hash)
93
- root = root[p.to_s]
65
+ key = path.first.to_s
66
+ rest = path[1..-1]
67
+
68
+ # stringify the key we're processing
69
+ if (self.has_key?(key.to_sym) rescue false)
70
+ self[key] = self.delete(key.to_sym)
94
71
  end
95
72
 
96
- if value.nil?
97
- root.reject!{|k,v| k.to_s == path.last.to_s }
73
+ if rest.empty?
74
+ if options[:delete_nil] === true and value.nil?
75
+ self.delete(key)
76
+ else
77
+ self[key] = value
78
+ end
98
79
  else
99
- root[path.last.to_s] = value
80
+ if self[key].is_a?(Array) and self[key].first.is_a?(Hash)
81
+ # set only on specific array items
82
+ if options[:index]
83
+ [*options[:index]].each do |i|
84
+ self[key][i].rset(rest, value, options.reject{|k|
85
+ k == :index
86
+ }) unless self[key][i].nil?
87
+ end
88
+
89
+ # set path on all array items
90
+ else
91
+ self[key] = self[key].collect{|v|
92
+ v.rset(rest, value, options)
93
+ }.compact
94
+ end
95
+ else
96
+ if not self[key].is_a?(Hash)
97
+ self[key] = {}
98
+ end
99
+
100
+ self[key].rset(rest, value, options)
101
+ end
102
+
100
103
  end
101
104
 
102
105
  self
103
106
  end
104
107
 
105
108
  def unset(path)
106
- set(path, nil)
109
+ rset(path, nil, {
110
+ :delete_nil => true
111
+ })
107
112
  end
108
113
 
109
114
  def rekey(from, to)
@@ -138,54 +143,47 @@ class Hash
138
143
  end
139
144
 
140
145
  def each_recurse(options={}, &block)
141
- options[:root] = self if options[:root].nil?
142
- options[:path] = [] if options[:path].nil?
143
-
144
- options[:root].each do |k,v|
145
- options[:path] << k
146
+ self.inject({}) do |h, (k, v)|
147
+ path = [*options[:path]]+[k]
148
+ h[k] = v
146
149
 
147
150
  if v.is_a?(Hash)
148
- yield(k, v, options[:path]) if options[:intermediate] === true
151
+ if options[:intermediate] === true
152
+ yield(k.to_s, v, path, h[k])
153
+ end
149
154
 
150
- each_recurse(options.merge({
151
- :root => v,
152
- :path => options[:path]
155
+ v.each_recurse(options.merge({
156
+ :path => path
153
157
  }), &block)
154
- else
155
- rv = yield(k, v, options[:path])
156
- self.set(options[:path], rv) if options[:inplace] === true
157
- end
158
-
159
- options[:path].pop
160
- end
161
- end
162
158
 
163
- def each_recurse!(options={}, &block)
164
- each_recurse(options.merge({
165
- :inplace => true
166
- }), &block)
167
- end
168
-
169
- def compact
170
- def _is_empty?(i)
171
- i === nil or (i.is_a?(String) and i.strip.chomp.empty?) or (i.respond_to?(:empty?) and i.empty?)
172
- end
173
-
174
- each_recurse do |k,v,path|
175
- path = path.join('.')
159
+ elsif v.is_a?(Array) and v.first.is_a?(Hash)
160
+ v.each_index do |i|
161
+ if v[i].is_a?(Hash)
162
+ if options[:intermediate] === true
163
+ yield(k.to_s, v[i], path, h[k][i], i)
164
+ end
176
165
 
177
- if v.is_a?(Array)
178
- v.reject!{|i| _is_empty?(i) }
179
- unset(path) if v.empty?
166
+ v[i].each_recurse(options.merge({
167
+ :path => path,
168
+ :index => i
169
+ }), &block)
170
+ end
171
+ end
180
172
 
181
173
  else
182
- unset(path) if _is_empty?(v)
174
+ rv = yield(k.to_s, v, path, h, options[:index])
183
175
  end
184
176
 
185
- nil
177
+ h
186
178
  end
179
+ end
187
180
 
188
- self
181
+ def compact()
182
+ return each_recurse do |k,v,p,out|
183
+ if v.nil? or (v.respond_to?(:empty?) and v.empty?)
184
+ out.delete(p)
185
+ end
186
+ end
189
187
  end
190
188
 
191
189
  def stringify_keys()
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashlib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.25
4
+ version: 0.0.30
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -40,7 +40,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
40
40
  version: '0'
41
41
  requirements: []
42
42
  rubyforge_project:
43
- rubygems_version: 1.8.11
43
+ rubygems_version: 1.8.23
44
44
  signing_key:
45
45
  specification_version: 3
46
46
  summary: Useful utility methods for working with Ruby hashes