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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b21feb448e04c5e66454eb31818b0b78e9d7e36e
4
- data.tar.gz: baa845fabc8a02be3239af3b21f8e1149796ccd3
3
+ metadata.gz: f2271ae81c6b0b63bc52231e263ed3eaf4d556cf
4
+ data.tar.gz: d94254c24fe5d6bedb163adbfedea3870f249b05
5
5
  SHA512:
6
- metadata.gz: 2f3805e7813acd3582fd6db84925969711e3cda216adfb7f219e6ee2d89ab3a5574a12bb160c60fa2df4f4429d9b87ca6686b1f88baf54113a8caa5591557b95
7
- data.tar.gz: c713ea6609db9fe3a257af5b01ea9fddb13f45d5e9ba2bd9f7bc48a3d955b6b141669e4eb23c1f48366216863a34c30dd1dc714b1f7d5c3660d074b2cab8f084
6
+ metadata.gz: 45d4cdf94d0425dd4e05a6906872ecb01470bff766c59608e5faa8d8cc4d2fb9fb4716b88278e073f51544502f7966b530867faedd481098f654c10a5a7fb7ad
7
+ data.tar.gz: f02a980973a1c1543101e1ef2ae3dbe4618aa61f590bf875c7285388fe3485e50bc720d3895590846c3045fd24541ec062dd9914a1dba20cf5cbc52cc3a480fa
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.66
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 deep_map(max_depth=nil, current_depth=0, parent=nil, &block)
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.deep_map(max_depth, current_depth+1, self, &block)
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 :recursive_map, :deep_map
186
- alias_method :map_recursively, :deep_map
187
- alias_method :map_recursive, :deep_map
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] ].deep_select{|e| e % 2 == 0 } #=> [ [2], [4] ]
194
+ # [ [1,2], [3,4] ].select_recursively{|e| e % 2 == 0 } #=> [ [2], [4] ]
195
195
  #
196
- def deep_select(max_depth=nil, current_depth=0, parent=nil, &block)
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
- p [:obj, obj]
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
- # def deep_select(depth=nil, &block)
224
- # map do |*args|
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
  #
@@ -907,8 +907,8 @@ class Path
907
907
  else
908
908
  #{command} path # Make the directory
909
909
  reload!
910
- self
911
910
  end
911
+ self
912
912
  end
913
913
  }
914
914
  end
@@ -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, "0", "off", "no", "false", "disabled", "disable"
53
+ when false, nil, 0, /^(0|off|no|false|disabled?)$/
54
54
  false
55
- when true, 1, "1", "on", "yes", "true", "enabled", "enable"
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
- name, type = spec.split(":")
72
+ case spec
73
+ when "*"
74
+ wildcard = true
75
+ next
76
+ when "-"
77
+ drop_unknown = true
78
+ next
79
+ end
70
80
 
71
- type ||= :passthru
81
+ names, type = spec.split(":")
72
82
 
73
- unless converter = CONVERTERS[type]
74
- raise "Unknown type: #{type}"
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
- [name.to_sym, converter]
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 = Hash[members.zip(args)]
127
+ opts = members.zip(args)
99
128
  end
100
129
 
101
- opts.each { |key,value| send "#{key}=", value }
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
@@ -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]].deep_map {|e| e ** 2}.should == [[1,4],[9,16]]
457
- [1,2,3,4].deep_map {|e| e ** 2}.should == [1,4,9,16]
458
- [[],[],1,2,3,4].deep_map {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
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]].deep_select {|e| e % 2 == 0 }.should == [[2],[4]]
465
- puts
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}
@@ -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
@@ -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.66
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-05 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec