rbbt-util 4.4.0 → 5.0.0
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.
- data/README.rdoc +3 -0
- data/bin/rbbt_exec.rb +6 -1
- data/bin/rbbt_monitor.rb +117 -0
- data/bin/run_workflow.rb +7 -3
- data/lib/rbbt/annotations.rb +147 -81
- data/lib/rbbt/fix_width_table.rb +5 -1
- data/lib/rbbt/persist.rb +51 -34
- data/lib/rbbt/persist/tsv.rb +26 -15
- data/lib/rbbt/resource.rb +14 -9
- data/lib/rbbt/resource/path.rb +5 -5
- data/lib/rbbt/resource/rake.rb +9 -5
- data/lib/rbbt/resource/util.rb +4 -2
- data/lib/rbbt/tsv.rb +23 -8
- data/lib/rbbt/tsv/accessor.rb +18 -5
- data/lib/rbbt/tsv/attach/util.rb +12 -2
- data/lib/rbbt/tsv/manipulate.rb +69 -16
- data/lib/rbbt/tsv/parser.rb +3 -2
- data/lib/rbbt/tsv/util.rb +5 -4
- data/lib/rbbt/util/chain_methods.rb +8 -8
- data/lib/rbbt/util/cmd.rb +1 -1
- data/lib/rbbt/util/misc.rb +118 -13
- data/lib/rbbt/util/open.rb +38 -14
- data/lib/rbbt/util/simpleDSL.rb +1 -1
- data/lib/rbbt/workflow.rb +5 -4
- data/lib/rbbt/workflow/accessor.rb +7 -5
- data/lib/rbbt/workflow/step.rb +50 -7
- data/test/rbbt/test_annotations.rb +29 -3
- data/test/rbbt/test_persist.rb +150 -0
- data/test/rbbt/test_tsv.rb +35 -0
- data/test/rbbt/tsv/test_accessor.rb +9 -0
- data/test/rbbt/util/test_misc.rb +17 -3
- data/test/rbbt/util/test_open.rb +21 -0
- data/test/rbbt/workflow/test_step.rb +41 -1
- metadata +140 -136
data/README.rdoc
CHANGED
data/bin/rbbt_exec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
|
3
4
|
code_file = ARGV[0]
|
4
5
|
output = ARGV[1]
|
5
6
|
|
@@ -13,7 +14,11 @@ code = case
|
|
13
14
|
end
|
14
15
|
|
15
16
|
begin
|
16
|
-
|
17
|
+
if code_file.nil?
|
18
|
+
data = instance_eval code
|
19
|
+
else
|
20
|
+
data = instance_eval code, code_file
|
21
|
+
end
|
17
22
|
rescue Exception
|
18
23
|
puts "#:rbbt_exec Error"
|
19
24
|
puts $!.message
|
data/bin/rbbt_monitor.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbbt-util'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'rbbt/util/simpleopt'
|
6
|
+
require 'rbbt/workflow/step'
|
7
|
+
|
8
|
+
options = SOPT.get("-l--list:-z--zombies:-e--errors:-c--clean:-n--name:-a--all:-w--wipe:-f--file*")
|
9
|
+
|
10
|
+
def info_files
|
11
|
+
Dir.glob('**/*.info')
|
12
|
+
end
|
13
|
+
|
14
|
+
def running?(info)
|
15
|
+
begin
|
16
|
+
Process.kill 0, info[:pid]
|
17
|
+
true
|
18
|
+
rescue
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def print_job(file, info, severity_color = nil)
|
24
|
+
clean_file = file.sub('.info','')
|
25
|
+
if $name
|
26
|
+
puts clean_file
|
27
|
+
else
|
28
|
+
info ||= {:status => :missing_info_file}
|
29
|
+
str = [clean_file, info[:status].to_s] * " [ STATUS = " + " ]"
|
30
|
+
str += " (#{running?(info)? :running : :zombie} #{info[:pid]})" if info.include? :pid
|
31
|
+
|
32
|
+
str = "#{severity_color}" << str << "\033[0m" if severity_color
|
33
|
+
puts str
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def list_jobs(options)
|
38
|
+
|
39
|
+
omit_ok = options[:zombies] || options[:errors]
|
40
|
+
|
41
|
+
info_files.each do |file|
|
42
|
+
clean_file = file.sub('.info','')
|
43
|
+
next if File.exists? clean_file
|
44
|
+
begin
|
45
|
+
info = YAML.load(Open.read(file))
|
46
|
+
rescue Exception
|
47
|
+
Log.debug "Error parsing info file: #{ file }"
|
48
|
+
info = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
color = case
|
52
|
+
when info[:status] == :error
|
53
|
+
Log::SEVERITY_COLOR[3]
|
54
|
+
when (info[:pid] and not running? info)
|
55
|
+
Log::SEVERITY_COLOR[2]
|
56
|
+
end
|
57
|
+
|
58
|
+
case
|
59
|
+
when (not omit_ok)
|
60
|
+
print_job file, info, color
|
61
|
+
when options[:zombies]
|
62
|
+
print_job file, info, color if info[:pid] and not running? info
|
63
|
+
when options[:errors]
|
64
|
+
print_job file, info, color if info[:status] == :error
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove_job(file)
|
71
|
+
clean_file = file.sub('.info','')
|
72
|
+
FileUtils.rm file if File.exists? file
|
73
|
+
FileUtils.rm clean_file if File.exists? clean_file
|
74
|
+
FileUtils.rm_rf clean_file + '.files' if File.exists? clean_file + '.files'
|
75
|
+
end
|
76
|
+
|
77
|
+
def clean_jobs(options)
|
78
|
+
info_files.each do |file|
|
79
|
+
clean_file = file.sub('.info','')
|
80
|
+
next if File.exists? clean_file
|
81
|
+
info = nil
|
82
|
+
begin
|
83
|
+
info = YAML.load(Open.read(file))
|
84
|
+
rescue
|
85
|
+
Log.debug "Error process #{ file }"
|
86
|
+
raise $!
|
87
|
+
end
|
88
|
+
case
|
89
|
+
when options[:all]
|
90
|
+
remove_job file
|
91
|
+
when (options[:zombies] and info[:pid] and not running? info)
|
92
|
+
remove_job file
|
93
|
+
when (options[:errors] and info[:status] == :error)
|
94
|
+
remove_job file
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
$name = options.delete :name
|
103
|
+
case
|
104
|
+
when (options[:clean] and not options[:list])
|
105
|
+
if options[:file]
|
106
|
+
remove_job options[:file]
|
107
|
+
else
|
108
|
+
clean_jobs options
|
109
|
+
end
|
110
|
+
else
|
111
|
+
if options[:file]
|
112
|
+
info = YAML.load(Open.read(options[:file]))
|
113
|
+
print_job options[:file], info
|
114
|
+
else
|
115
|
+
list_jobs options
|
116
|
+
end
|
117
|
+
end
|
data/bin/run_workflow.rb
CHANGED
@@ -85,6 +85,7 @@ options = SOPT.get "-t--task*:-l--log*:-h--help:-n--name*:-cl--clean:-rcl-recurs
|
|
85
85
|
workflow = ARGV.first
|
86
86
|
|
87
87
|
if options[:server]
|
88
|
+
|
88
89
|
require 'rbbt/util/log'
|
89
90
|
require 'rbbt/workflow'
|
90
91
|
require 'rbbt/workflow/rest'
|
@@ -98,10 +99,16 @@ if options[:server]
|
|
98
99
|
|
99
100
|
Sinatra::Application.port = options[:port] || 4567
|
100
101
|
Sinatra::Application.run = true
|
102
|
+
|
101
103
|
if File.exists? workflow
|
102
104
|
Sinatra::Application.views = File.join(File.dirname(workflow), 'www/views')
|
103
105
|
end
|
104
106
|
|
107
|
+
sinatra_file = './lib/sinatra.rb'
|
108
|
+
if File.exists? sinatra_file
|
109
|
+
require sinatra_file
|
110
|
+
end
|
111
|
+
|
105
112
|
else
|
106
113
|
|
107
114
|
# Set log, fork, clean, recursive_clean and help
|
@@ -182,9 +189,6 @@ else
|
|
182
189
|
Log.low "Job name: #{job.name}"
|
183
190
|
end
|
184
191
|
|
185
|
-
#- error
|
186
|
-
|
187
|
-
#print
|
188
192
|
case
|
189
193
|
when Array === res
|
190
194
|
puts res * "\n"
|
data/lib/rbbt/annotations.rb
CHANGED
@@ -20,9 +20,16 @@ module Annotated
|
|
20
20
|
end.flatten.uniq
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def unmasked_annotations
|
24
|
+
raise "Annotation types is nil for object: #{self.inspect}" if annotation_types.nil?
|
25
|
+
annotation_types.collect do |mod|
|
26
|
+
mod.unmasked_annotations
|
27
|
+
end.flatten.uniq
|
28
|
+
end
|
29
|
+
|
30
|
+
def info(masked = false)
|
24
31
|
hash = {:annotation_types => annotation_types}
|
25
|
-
annotations.each do |annotation|
|
32
|
+
(masked ? unmasked_annotations : annotations).each do |annotation|
|
26
33
|
value = self.send(annotation)
|
27
34
|
hash[annotation] = value unless value.nil?
|
28
35
|
end
|
@@ -39,12 +46,17 @@ module Annotated
|
|
39
46
|
|
40
47
|
return object if annotation_types.nil? or annotation_types.empty?
|
41
48
|
|
49
|
+
annotated_array = info.delete(:annotated_array) || false
|
50
|
+
|
42
51
|
annotation_types.each do |mod|
|
43
52
|
mod = Misc.string2const(mod) if String === mod
|
44
53
|
mod.setup(object, *info.values_at(*mod.all_annotations))
|
45
54
|
end
|
46
55
|
|
47
56
|
object.id = info[:entity_id] if info.include? :entity_id
|
57
|
+
|
58
|
+
object.extend AnnotatedArray if annotated_array
|
59
|
+
|
48
60
|
object
|
49
61
|
end
|
50
62
|
|
@@ -54,6 +66,7 @@ module Annotated
|
|
54
66
|
else
|
55
67
|
fields = fields.flatten
|
56
68
|
info = self.info
|
69
|
+
info[:annotated_array] = true if AnnotatedArray === self
|
57
70
|
values = []
|
58
71
|
|
59
72
|
fields.each do |field|
|
@@ -79,6 +92,14 @@ module Annotated
|
|
79
92
|
end
|
80
93
|
end
|
81
94
|
|
95
|
+
def self.resolve_array(entry)
|
96
|
+
if entry =~ /^Array:/
|
97
|
+
entry["Array:".length..-1].split("|")
|
98
|
+
else
|
99
|
+
entry
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
82
103
|
def self.load_tsv_values(id, values, *fields)
|
83
104
|
fields = fields.flatten
|
84
105
|
info = {}
|
@@ -91,7 +112,7 @@ module Annotated
|
|
91
112
|
id.dup
|
92
113
|
end
|
93
114
|
|
94
|
-
object = object
|
115
|
+
object = resolve_array(object)
|
95
116
|
|
96
117
|
if Array === values.first
|
97
118
|
Misc.zip_fields(values).collect do |list|
|
@@ -101,7 +122,7 @@ module Annotated
|
|
101
122
|
info[key.to_sym] = value
|
102
123
|
end
|
103
124
|
else
|
104
|
-
info[field.to_sym] = list[i]
|
125
|
+
info[field.to_sym] = resolve_array(list[i])
|
105
126
|
end
|
106
127
|
end
|
107
128
|
end
|
@@ -112,7 +133,7 @@ module Annotated
|
|
112
133
|
info[key.to_sym] = value
|
113
134
|
end
|
114
135
|
else
|
115
|
-
info[field.to_sym] = values[i]
|
136
|
+
info[field.to_sym] = resolve_array(values[i])
|
116
137
|
end
|
117
138
|
end
|
118
139
|
end
|
@@ -162,11 +183,13 @@ module Annotated
|
|
162
183
|
case
|
163
184
|
when (Annotated === annotations and not (AnnotatedArray === annotations and annotations.double_array))
|
164
185
|
tsv = TSV.setup({}, :key_field => "List", :fields => fields, :type => :list, :unnamed => true)
|
165
|
-
|
186
|
+
annot_id = annotations.id
|
187
|
+
tsv[annot_id] = annotations.tsv_values(*fields)
|
166
188
|
when Array === annotations
|
167
189
|
tsv = TSV.setup({}, :key_field => "ID", :fields => fields, :type => :list, :unnamed => true)
|
168
|
-
annotations.compact.
|
169
|
-
tsv[annotation.id] = annotation.tsv_values(*fields)
|
190
|
+
annotations.compact.each_with_index do |annotation,i|
|
191
|
+
tsv[annotation.id + ":" << i.to_s] = annotation.tsv_values(*fields)
|
192
|
+
#tsv[annotation.id] = annotation.tsv_values(*fields)
|
170
193
|
end
|
171
194
|
else
|
172
195
|
raise "Annotations need to be an Array to create TSV"
|
@@ -214,11 +237,16 @@ module Annotation
|
|
214
237
|
def self.extended(base)
|
215
238
|
if not base.respond_to? :annotations
|
216
239
|
class << base
|
217
|
-
attr_accessor :annotations, :inheritance, :all_inheritance, :all_annotations
|
240
|
+
attr_accessor :annotations, :inheritance, :all_inheritance, :all_annotations, :masked_annotations
|
241
|
+
|
242
|
+
def unmasked_annotations
|
243
|
+
annotations - masked_annotations
|
244
|
+
end
|
218
245
|
self
|
219
246
|
end
|
220
247
|
|
221
248
|
base.annotations = []
|
249
|
+
base.masked_annotations = []
|
222
250
|
base.inheritance = []
|
223
251
|
base.all_annotations = []
|
224
252
|
base.all_inheritance = []
|
@@ -230,12 +258,12 @@ module Annotation
|
|
230
258
|
|
231
259
|
def self.extended(object)
|
232
260
|
self.send(:prev_annotation_extended, object)
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
261
|
+
object.extend Annotated unless Annotated === object
|
262
|
+
if not object.annotation_types.include? self
|
263
|
+
object.annotation_types.concat self.inheritance
|
264
|
+
object.annotation_types << self
|
265
|
+
object.annotation_types.uniq!
|
266
|
+
end
|
239
267
|
end
|
240
268
|
|
241
269
|
def self.included(base)
|
@@ -271,17 +299,26 @@ module Annotation
|
|
271
299
|
end
|
272
300
|
|
273
301
|
def setup(object, *values)
|
302
|
+
return nil if object.nil?
|
303
|
+
|
274
304
|
object.extend self unless self === object
|
275
305
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
306
|
+
if Hash === values.last
|
307
|
+
values.last.each do |name, value|
|
308
|
+
setter = "#{name}="
|
309
|
+
next unless object.respond_to? setter
|
310
|
+
value = value.split("|") if String === value and value.index "|"
|
311
|
+
object.send("#{name}=", value)
|
312
|
+
end
|
313
|
+
else
|
314
|
+
all_annotations.zip(values).each do |name, value|
|
315
|
+
value = value.split("|") if String === value and value.index "|"
|
316
|
+
object.send("#{name}=", value)
|
317
|
+
end
|
280
318
|
end
|
281
319
|
|
282
320
|
object
|
283
321
|
end
|
284
|
-
|
285
322
|
end
|
286
323
|
|
287
324
|
module AnnotatedArray
|
@@ -290,57 +327,74 @@ module AnnotatedArray
|
|
290
327
|
self.chain_prefix = :annotated_array
|
291
328
|
|
292
329
|
def double_array
|
293
|
-
AnnotatedArray === self.
|
330
|
+
AnnotatedArray === self.send(:[], 0, true)
|
294
331
|
end
|
295
332
|
|
296
|
-
def
|
333
|
+
def first
|
297
334
|
self[0]
|
298
335
|
end
|
299
336
|
|
300
|
-
def
|
337
|
+
def last
|
301
338
|
self[-1]
|
302
339
|
end
|
303
340
|
|
304
|
-
def
|
305
|
-
value =
|
341
|
+
def [](pos, clean = false)
|
342
|
+
value = super(pos)
|
343
|
+
return nil if value.nil?
|
344
|
+
return value if clean
|
345
|
+
return value unless String === value or Array === value
|
346
|
+
|
306
347
|
value = value.dup if value.frozen?
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
value.context = self.context
|
312
|
-
value.container = self
|
313
|
-
value.container_index = pos
|
348
|
+
|
349
|
+
annotation_types.each do |mod|
|
350
|
+
value.extend mod unless mod === value
|
351
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s << "=", self.send(annotation)) end
|
314
352
|
end
|
353
|
+
|
354
|
+
value.context = self.context
|
355
|
+
value.container = self
|
356
|
+
value.container_index = pos
|
357
|
+
|
358
|
+
value.extend AnnotatedArray if Array === value and AnnotatedArray === self
|
359
|
+
|
315
360
|
value
|
316
361
|
end
|
317
362
|
|
318
|
-
def
|
363
|
+
def each
|
319
364
|
i = 0
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
365
|
+
info = info
|
366
|
+
super do |value|
|
367
|
+
if String === value or Array === value
|
368
|
+
value = value.dup if value.frozen? and not value.nil?
|
369
|
+
|
370
|
+
annotation_types.each do |mod|
|
371
|
+
value.extend mod unless mod === value
|
372
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s << "=", self.send(annotation)) end
|
373
|
+
end
|
374
|
+
|
375
|
+
value.extend AnnotatedArray if Array === value and AnnotatedArray === self
|
376
|
+
|
326
377
|
value.context = self.context
|
327
378
|
value.container = self
|
328
379
|
value.container_index = i
|
380
|
+
|
329
381
|
end
|
382
|
+
|
330
383
|
i += 1
|
384
|
+
|
331
385
|
yield value
|
332
386
|
end
|
333
387
|
end
|
334
388
|
|
335
|
-
def
|
389
|
+
def collect
|
336
390
|
res = []
|
337
391
|
|
338
392
|
if block_given?
|
339
|
-
|
393
|
+
each do |value|
|
340
394
|
res << yield(value)
|
341
395
|
end
|
342
396
|
else
|
343
|
-
|
397
|
+
each do |value|
|
344
398
|
res << value
|
345
399
|
end
|
346
400
|
end
|
@@ -348,18 +402,19 @@ module AnnotatedArray
|
|
348
402
|
res
|
349
403
|
end
|
350
404
|
|
351
|
-
def
|
405
|
+
def select(method = nil, *args)
|
352
406
|
res = []
|
353
407
|
if method
|
354
408
|
res = self.zip(self.send(method, *args)).select{|e,result| result}.collect{|element,r| element}
|
355
409
|
else
|
356
|
-
|
410
|
+
each do |value|
|
357
411
|
res << value if yield(value)
|
358
412
|
end
|
359
413
|
end
|
360
414
|
|
361
|
-
annotation_types.each do |mod|
|
362
|
-
|
415
|
+
annotation_types.each do |mod|
|
416
|
+
res.extend mod unless mod === res
|
417
|
+
mod.annotations.each do |annotation| res.send(annotation.to_s + "=", self.send(annotation)) end
|
363
418
|
end
|
364
419
|
|
365
420
|
res.context = self.context
|
@@ -370,15 +425,17 @@ module AnnotatedArray
|
|
370
425
|
res
|
371
426
|
end
|
372
427
|
|
373
|
-
def
|
428
|
+
def reject
|
374
429
|
res = []
|
375
|
-
|
430
|
+
each do |value|
|
376
431
|
res << value unless yield(value)
|
377
432
|
end
|
378
433
|
|
379
|
-
annotation_types.each do |mod|
|
380
|
-
|
434
|
+
annotation_types.each do |mod|
|
435
|
+
res.extend mod unless mod === res
|
436
|
+
mod.annotations.each do |annotation| res.send(annotation.to_s + "=", self.send(annotation)) end
|
381
437
|
end
|
438
|
+
|
382
439
|
res.context = self.context
|
383
440
|
res.container = self.container
|
384
441
|
|
@@ -387,11 +444,12 @@ module AnnotatedArray
|
|
387
444
|
res
|
388
445
|
end
|
389
446
|
|
390
|
-
def
|
447
|
+
def subset(list)
|
391
448
|
value = (self & list)
|
392
449
|
|
393
|
-
annotation_types.each do |mod|
|
394
|
-
|
450
|
+
annotation_types.each do |mod|
|
451
|
+
value.extend mod unless mod === value
|
452
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
395
453
|
end
|
396
454
|
|
397
455
|
value.context = self.context
|
@@ -402,11 +460,12 @@ module AnnotatedArray
|
|
402
460
|
value
|
403
461
|
end
|
404
462
|
|
405
|
-
def
|
463
|
+
def remove(list)
|
406
464
|
value = (self - list)
|
407
465
|
|
408
|
-
annotation_types.each do |mod|
|
409
|
-
|
466
|
+
annotation_types.each do |mod|
|
467
|
+
value.extend mod unless mod === value
|
468
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
410
469
|
end
|
411
470
|
|
412
471
|
value.context = self.context
|
@@ -417,11 +476,12 @@ module AnnotatedArray
|
|
417
476
|
value
|
418
477
|
end
|
419
478
|
|
420
|
-
def
|
421
|
-
value =
|
479
|
+
def compact
|
480
|
+
value = super
|
422
481
|
|
423
|
-
annotation_types.each do |mod|
|
424
|
-
|
482
|
+
annotation_types.each do |mod|
|
483
|
+
value.extend mod unless mod === value
|
484
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
425
485
|
end
|
426
486
|
|
427
487
|
value.context = self.context
|
@@ -432,11 +492,12 @@ module AnnotatedArray
|
|
432
492
|
value
|
433
493
|
end
|
434
494
|
|
435
|
-
def
|
436
|
-
value =
|
495
|
+
def uniq
|
496
|
+
value = super
|
437
497
|
|
438
|
-
annotation_types.each do |mod|
|
439
|
-
|
498
|
+
annotation_types.each do |mod|
|
499
|
+
value.extend mod unless mod === value
|
500
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
440
501
|
end
|
441
502
|
|
442
503
|
value.context = self.context
|
@@ -447,11 +508,12 @@ module AnnotatedArray
|
|
447
508
|
value
|
448
509
|
end
|
449
510
|
|
450
|
-
def
|
451
|
-
value =
|
511
|
+
def flatten
|
512
|
+
value = super.dup
|
452
513
|
|
453
|
-
annotation_types.each do |mod|
|
454
|
-
|
514
|
+
annotation_types.each do |mod|
|
515
|
+
value.extend mod unless mod === value
|
516
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
455
517
|
end
|
456
518
|
|
457
519
|
value.context = self.context
|
@@ -462,11 +524,12 @@ module AnnotatedArray
|
|
462
524
|
value
|
463
525
|
end
|
464
526
|
|
465
|
-
def
|
466
|
-
value =
|
527
|
+
def reverse
|
528
|
+
value = super
|
467
529
|
|
468
|
-
annotation_types.each do |mod|
|
469
|
-
|
530
|
+
annotation_types.each do |mod|
|
531
|
+
value.extend mod unless mod === value
|
532
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
470
533
|
end
|
471
534
|
|
472
535
|
value.context = self.context
|
@@ -477,11 +540,12 @@ module AnnotatedArray
|
|
477
540
|
value
|
478
541
|
end
|
479
542
|
|
480
|
-
def
|
481
|
-
value =
|
543
|
+
def sort_by(&block)
|
544
|
+
value = super &block
|
482
545
|
|
483
|
-
annotation_types.each do |mod|
|
484
|
-
|
546
|
+
annotation_types.each do |mod|
|
547
|
+
value.extend mod unless mod === value
|
548
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
485
549
|
end
|
486
550
|
|
487
551
|
value.context = self.context
|
@@ -492,11 +556,12 @@ module AnnotatedArray
|
|
492
556
|
value
|
493
557
|
end
|
494
558
|
|
495
|
-
def
|
559
|
+
def sort(&block)
|
496
560
|
value = self.collect.sort(&block).collect{|value| value.respond_to?(:clean_annotations) ? value.clean_annotations.dup : value.dup }
|
497
561
|
|
498
|
-
annotation_types.each do |mod|
|
499
|
-
|
562
|
+
annotation_types.each do |mod|
|
563
|
+
value.extend mod unless mod === value
|
564
|
+
mod.annotations.each do |annotation| value.send(annotation.to_s + "=", self.send(annotation)) end
|
500
565
|
end
|
501
566
|
|
502
567
|
value.extend AnnotatedArray if AnnotatedArray === self
|
@@ -504,7 +569,7 @@ module AnnotatedArray
|
|
504
569
|
value
|
505
570
|
end
|
506
571
|
|
507
|
-
def
|
572
|
+
def select_by(method)
|
508
573
|
case
|
509
574
|
when (Symbol === method or String === method)
|
510
575
|
method = self.send(method)
|
@@ -516,7 +581,7 @@ module AnnotatedArray
|
|
516
581
|
|
517
582
|
value = []
|
518
583
|
|
519
|
-
|
584
|
+
super do |e|
|
520
585
|
value << e if method.shift
|
521
586
|
end
|
522
587
|
|
@@ -530,3 +595,4 @@ module AnnotatedArray
|
|
530
595
|
end
|
531
596
|
|
532
597
|
end
|
598
|
+
|