hashlib 0.0.25 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
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