epitools 0.5.66 → 0.5.67
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/epitools/core_ext/enumerable.rb +15 -48
- data/lib/epitools/path.rb +1 -1
- data/lib/epitools/typed_struct.rb +47 -10
- data/spec/core_ext_spec.rb +15 -11
- data/spec/path_spec.rb +7 -0
- data/spec/typed_struct_spec.rb +35 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2271ae81c6b0b63bc52231e263ed3eaf4d556cf
|
4
|
+
data.tar.gz: d94254c24fe5d6bedb163adbfedea3870f249b05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45d4cdf94d0425dd4e05a6906872ecb01470bff766c59608e5faa8d8cc4d2fb9fb4716b88278e073f51544502f7966b530867faedd481098f654c10a5a7fb7ad
|
7
|
+
data.tar.gz: f02a980973a1c1543101e1ef2ae3dbe4618aa61f590bf875c7285388fe3485e50bc720d3895590846c3045fd24541ec062dd9914a1dba20cf5cbc52cc3a480fa
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.67
|
@@ -17,7 +17,6 @@ module Enumerable
|
|
17
17
|
#
|
18
18
|
alias_method :includes?, :include?
|
19
19
|
|
20
|
-
|
21
20
|
#
|
22
21
|
# Skip the first n elements and return an Enumerator for the rest, or pass them
|
23
22
|
# in succession to the block, if given. This is like "drop", but returns an enumerator
|
@@ -158,12 +157,13 @@ module Enumerable
|
|
158
157
|
|
159
158
|
#
|
160
159
|
# The same as "map", except that if an element is an Array or Enumerable, map is called
|
161
|
-
# recursively on that element.
|
160
|
+
# recursively on that element. (Hashes are ignored because of the complications of block
|
161
|
+
# arguments and return values.)
|
162
162
|
#
|
163
163
|
# Example:
|
164
164
|
# [ [1,2], [3,4] ].deep_map{|e| e ** 2 } #=> [ [1,4], [9,16] ]
|
165
165
|
#
|
166
|
-
def
|
166
|
+
def map_recursively(max_depth=nil, current_depth=0, parent=nil, &block)
|
167
167
|
return self if max_depth and (current_depth > max_depth)
|
168
168
|
|
169
169
|
map do |obj|
|
@@ -171,10 +171,10 @@ module Enumerable
|
|
171
171
|
yield obj
|
172
172
|
else
|
173
173
|
case obj
|
174
|
-
when String
|
174
|
+
when String, Hash
|
175
175
|
yield obj
|
176
176
|
when Enumerable
|
177
|
-
obj.
|
177
|
+
obj.map_recursively(max_depth, current_depth+1, self, &block)
|
178
178
|
else
|
179
179
|
yield obj
|
180
180
|
end
|
@@ -182,69 +182,39 @@ module Enumerable
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
-
alias_method :
|
186
|
-
alias_method :
|
187
|
-
alias_method :map_recursive,
|
185
|
+
alias_method :deep_map, :map_recursively
|
186
|
+
alias_method :recursive_map, :map_recursively
|
187
|
+
alias_method :map_recursive, :map_recursively
|
188
188
|
|
189
189
|
#
|
190
190
|
# The same as "select", except that if an element is an Array or Enumerable, select is called
|
191
191
|
# recursively on that element.
|
192
192
|
#
|
193
193
|
# Example:
|
194
|
-
# [ [1,2], [3,4] ].
|
194
|
+
# [ [1,2], [3,4] ].select_recursively{|e| e % 2 == 0 } #=> [ [2], [4] ]
|
195
195
|
#
|
196
|
-
def
|
196
|
+
def select_recursively(max_depth=nil, current_depth=0, parent=nil, &block)
|
197
197
|
return self if max_depth and (current_depth > max_depth)
|
198
198
|
|
199
199
|
map do |obj|
|
200
|
-
|
201
|
-
result = if obj == parent # infinite loop scenario!
|
202
|
-
p :infinite
|
200
|
+
if obj == parent # infinite loop scenario!
|
203
201
|
obj if yield obj
|
204
202
|
else
|
205
203
|
case obj
|
206
|
-
when String
|
207
|
-
p :string
|
204
|
+
when String, Hash
|
208
205
|
obj if yield obj
|
209
206
|
when Enumerable
|
210
|
-
p :recurse
|
211
207
|
obj.deep_select(max_depth, current_depth+1, self, &block)
|
212
208
|
else
|
213
|
-
p :else
|
214
|
-
p [:yield, yield(obj)]
|
215
209
|
obj if yield obj
|
216
210
|
end
|
217
211
|
end
|
218
|
-
p [:result, result]
|
219
|
-
result
|
220
212
|
end.compact
|
221
213
|
end
|
222
214
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
# obj = args.last
|
227
|
-
|
228
|
-
# if depth.nil? or depth > 0
|
229
|
-
|
230
|
-
# case obj
|
231
|
-
# when Hash
|
232
|
-
|
233
|
-
# when Array, Enumerable
|
234
|
-
# result = obj.deep_select(depth ? depth-1 : nil, &block)
|
235
|
-
# result.any? ? result : nil
|
236
|
-
# end
|
237
|
-
|
238
|
-
# else
|
239
|
-
# obj if block.call(obj)
|
240
|
-
# end
|
241
|
-
|
242
|
-
# end.compact
|
243
|
-
# end
|
244
|
-
|
245
|
-
alias_method :recursive_select, :deep_select
|
246
|
-
alias_method :select_recursively, :deep_select
|
247
|
-
alias_method :select_recursive, :deep_select
|
215
|
+
alias_method :deep_select, :select_recursively
|
216
|
+
alias_method :recursive_select, :select_recursively
|
217
|
+
alias_method :select_recursive, :select_recursively
|
248
218
|
|
249
219
|
#
|
250
220
|
# Identical to "reduce" in ruby1.9 (or foldl in haskell.)
|
@@ -349,7 +319,6 @@ module Enumerable
|
|
349
319
|
end
|
350
320
|
alias_method :group_neighbors_by, :group_neighbours_by
|
351
321
|
|
352
|
-
|
353
322
|
#
|
354
323
|
# Convert the array into a stable iterator (Iter) object.
|
355
324
|
#
|
@@ -376,7 +345,6 @@ module Enumerable
|
|
376
345
|
alias_method :count_by, :counts
|
377
346
|
alias_method :group_counts, :counts
|
378
347
|
|
379
|
-
|
380
348
|
#
|
381
349
|
# group_by the elements themselves
|
382
350
|
#
|
@@ -385,7 +353,6 @@ module Enumerable
|
|
385
353
|
end
|
386
354
|
alias_method :grouped, :groups
|
387
355
|
|
388
|
-
|
389
356
|
#
|
390
357
|
# Multiplies this Enumerable by something. (Same behaviour as Enumerator#*)
|
391
358
|
#
|
data/lib/epitools/path.rb
CHANGED
@@ -50,9 +50,9 @@ class TypedStruct < Struct
|
|
50
50
|
["timestamp", "unixtime"] => proc { |me| Time.at me },
|
51
51
|
["bool", "boolean"] => proc do |me|
|
52
52
|
case me
|
53
|
-
when false, nil, 0,
|
53
|
+
when false, nil, 0, /^(0|off|no|false|disabled?)$/
|
54
54
|
false
|
55
|
-
when true, 1,
|
55
|
+
when true, 1, /^(1|on|yes|true|enabled?)$/
|
56
56
|
true
|
57
57
|
else
|
58
58
|
raise "Invalid boolean type: #{me.inspect}"
|
@@ -64,18 +64,30 @@ class TypedStruct < Struct
|
|
64
64
|
# Initialize a new struct.
|
65
65
|
#
|
66
66
|
def self.[](specs)
|
67
|
+
wildcard = false
|
68
|
+
drop_unknown = false
|
69
|
+
|
67
70
|
# create [name,type] pairs
|
68
71
|
pairs = specs.split.map do |spec|
|
69
|
-
|
72
|
+
case spec
|
73
|
+
when "*"
|
74
|
+
wildcard = true
|
75
|
+
next
|
76
|
+
when "-"
|
77
|
+
drop_unknown = true
|
78
|
+
next
|
79
|
+
end
|
70
80
|
|
71
|
-
type
|
81
|
+
names, type = spec.split(":")
|
72
82
|
|
73
|
-
|
74
|
-
|
83
|
+
names.split(",").map do |name|
|
84
|
+
type ||= :passthru
|
85
|
+
raise "Unknown type: #{type}" unless converter = CONVERTERS[type]
|
86
|
+
[name.to_sym, converter]
|
75
87
|
end
|
88
|
+
end.compact.flatten(1)
|
76
89
|
|
77
|
-
|
78
|
-
end
|
90
|
+
raise "Error: Can't specify both wildcard ('*') and drop unknown ('-')" if wildcard and drop_unknown
|
79
91
|
|
80
92
|
# initialize the Struct
|
81
93
|
struct = new(*pairs.transpose.first)
|
@@ -88,6 +100,23 @@ class TypedStruct < Struct
|
|
88
100
|
end
|
89
101
|
end
|
90
102
|
|
103
|
+
if wildcard
|
104
|
+
struct.class_eval do
|
105
|
+
def method_missing(name, val=nil)
|
106
|
+
if name =~ /^(.+)=$/
|
107
|
+
@extra_slots ||= {}
|
108
|
+
@extra_slots[$1.to_sym] = val
|
109
|
+
else
|
110
|
+
@extra_slots && @extra_slots[name]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
struct.class_eval do
|
117
|
+
@@drop_unknown = drop_unknown
|
118
|
+
end
|
119
|
+
|
91
120
|
struct
|
92
121
|
end
|
93
122
|
|
@@ -95,10 +124,18 @@ class TypedStruct < Struct
|
|
95
124
|
if args.size == 1 and args.first.is_a? Hash
|
96
125
|
opts = args.first
|
97
126
|
else
|
98
|
-
opts =
|
127
|
+
opts = members.zip(args)
|
99
128
|
end
|
100
129
|
|
101
|
-
|
130
|
+
if @@drop_unknown
|
131
|
+
opts.each { |key,value| send "#{key}=", value if respond_to? "#{key}=" }
|
132
|
+
else
|
133
|
+
opts.each { |key,value| send "#{key}=", value }
|
134
|
+
end
|
102
135
|
end
|
103
136
|
|
104
137
|
end
|
138
|
+
|
139
|
+
def TypedStruct(schema)
|
140
|
+
TypedStruct[schema]
|
141
|
+
end
|
data/spec/core_ext_spec.rb
CHANGED
@@ -453,20 +453,14 @@ describe Enumerable do
|
|
453
453
|
it "maps deeply" do
|
454
454
|
[["a\n", "b\n"], ["c\n", "d\n"]].map_recursively(&:strip).should == [ %w[a b], %w[c d] ]
|
455
455
|
|
456
|
-
[[1,2],[3,4]].
|
457
|
-
[1,2,3,4].
|
458
|
-
[[],[],1,2,3,4].
|
459
|
-
|
460
|
-
{1=>2, 3=>{4=>5, 6=>7}}.deep_map {|k,v| [k, v**2] }.should == [ [1,4], [3, [[4,25], [6,49]]] ]
|
456
|
+
[[1,2],[3,4]].map_recursively {|e| e ** 2}.should == [[1,4],[9,16]]
|
457
|
+
[1,2,3,4].map_recursively {|e| e ** 2}.should == [1,4,9,16]
|
458
|
+
[[],[],1,2,3,4].map_recursively {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
|
461
459
|
end
|
462
460
|
|
463
461
|
it "selects deeply" do
|
464
|
-
[[1,2],[3,4]].
|
465
|
-
|
466
|
-
|
467
|
-
{1=>2, 3=>{4=>5, 6=>7}}.deep_select {|k,v| k == 1 }.should == {1=>2}
|
468
|
-
#[1,2,3,4].deep_select {|e| e ** 2}.should == [1,4,9,16]
|
469
|
-
#[[],[],1,2,3,4].deep_select {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
|
462
|
+
[[1,2],[3,4]].select_recursively {|e| e % 2 == 0 }.should == [[2],[4]]
|
463
|
+
[{},"Blah",1,2,3,4].select_recursively {|e| e == 2 }.should == [2]
|
470
464
|
end
|
471
465
|
|
472
466
|
it "splits" do
|
@@ -605,6 +599,16 @@ describe Hash do
|
|
605
599
|
before :each do
|
606
600
|
@h = {"key1"=>"val1", "key2"=>"val2"}
|
607
601
|
end
|
602
|
+
|
603
|
+
it "maps recursively" do
|
604
|
+
# nevermind. hashes are stupid.
|
605
|
+
# {a: 2, b: {c: 5, d: 7}}.map_recursively {|k,v| [k, v**2] }.should == {a: 4, b: {c: 25, d: 49}}
|
606
|
+
end
|
607
|
+
|
608
|
+
it "selects recursively" do
|
609
|
+
# nevermind. hashes are stupid.
|
610
|
+
# {1=>2, 3=>{4=>5, 6=>7}}.select_recursively {|k,v| k == 1 }.should == {1=>2}
|
611
|
+
end
|
608
612
|
|
609
613
|
it "maps keys" do
|
610
614
|
h = @h.map_keys{|k| k.upcase}
|
data/spec/path_spec.rb
CHANGED
@@ -310,6 +310,13 @@ describe Path do
|
|
310
310
|
tmp.rm
|
311
311
|
tmp.mkdir.should be_truthy
|
312
312
|
tmp.rm.should be_truthy
|
313
|
+
|
314
|
+
tmp2 = Path.tmpfile
|
315
|
+
tmp2.rm
|
316
|
+
tmp2 = tmp2/"nonexistent"/"directory"
|
317
|
+
|
318
|
+
tmp2.exists?.should == false
|
319
|
+
lambda { tmp2.mkdir_p }.should_not raise_error
|
313
320
|
end
|
314
321
|
|
315
322
|
it "has classmethods" do
|
data/spec/typed_struct_spec.rb
CHANGED
@@ -11,6 +11,41 @@ describe TypedStruct do
|
|
11
11
|
t.c = "yes"; t.c.should == true
|
12
12
|
#t.c?.should == true
|
13
13
|
end
|
14
|
+
|
15
|
+
it "compact syntaxes" do
|
16
|
+
t = TypedStruct["a,b:int c,d:bool"].new(1,2,1,0)
|
17
|
+
t.a.should == 1
|
18
|
+
t.b.should == 2
|
19
|
+
t.c.should == true
|
20
|
+
t.d.should == false
|
21
|
+
end
|
22
|
+
|
23
|
+
it "wildcardses" do
|
24
|
+
t = TypedStruct["a:int *"].new
|
25
|
+
|
26
|
+
t.a.should == nil
|
27
|
+
t.a = "111"; t.a.should == 111
|
28
|
+
|
29
|
+
t.q.should == nil
|
30
|
+
t.q = "111"; t.q.should == "111"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "drops unknowns" do
|
34
|
+
|
35
|
+
ts = TypedStruct["a:int"]
|
36
|
+
lambda { ts.new a: 1, b: 2 }.should raise_error
|
37
|
+
|
38
|
+
ts = TypedStruct["a:int -"]
|
39
|
+
lambda {
|
40
|
+
t = ts.new a: 1, b: 2
|
41
|
+
t.a.should == 1
|
42
|
+
lambda { t.b }.should raise_error
|
43
|
+
}.should_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can't use wildcard and drop unknown at once" do
|
47
|
+
lambda { TypedStruct["a:int - *"].new }.should raise_error
|
48
|
+
end
|
14
49
|
|
15
50
|
end
|
16
51
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epitools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.67
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- epitron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|