epitools 0.5.66 → 0.5.67
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.
- 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
|