rbbt-util 3.2.1 → 4.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.
Files changed (85) hide show
  1. data/README.rdoc +65 -0
  2. data/bin/run_workflow.rb +142 -69
  3. data/lib/rbbt-util.rb +3 -3
  4. data/lib/rbbt.rb +12 -3
  5. data/lib/rbbt/annotations.rb +215 -0
  6. data/lib/rbbt/{util/fix_width_table.rb → fix_width_table.rb} +17 -13
  7. data/lib/rbbt/persist.rb +164 -0
  8. data/lib/rbbt/persist/tsv.rb +135 -0
  9. data/lib/rbbt/resource.rb +100 -0
  10. data/lib/rbbt/resource/path.rb +180 -0
  11. data/lib/rbbt/resource/rake.rb +48 -0
  12. data/lib/rbbt/resource/util.rb +111 -0
  13. data/lib/rbbt/resource/with_key.rb +28 -0
  14. data/lib/rbbt/tsv.rb +134 -0
  15. data/lib/rbbt/tsv/accessor.rb +345 -0
  16. data/lib/rbbt/tsv/attach.rb +183 -0
  17. data/lib/rbbt/tsv/attach/util.rb +277 -0
  18. data/lib/rbbt/{util/tsv/filters.rb → tsv/filter.rb} +76 -37
  19. data/lib/rbbt/tsv/index.rb +453 -0
  20. data/lib/rbbt/tsv/manipulate.rb +361 -0
  21. data/lib/rbbt/tsv/parser.rb +231 -0
  22. data/lib/rbbt/tsv/serializers.rb +79 -0
  23. data/lib/rbbt/tsv/util.rb +67 -0
  24. data/lib/rbbt/util/R.rb +3 -3
  25. data/lib/rbbt/util/chain_methods.rb +64 -0
  26. data/lib/rbbt/util/cmd.rb +17 -13
  27. data/lib/rbbt/util/excel2tsv.rb +4 -3
  28. data/lib/rbbt/util/log.rb +1 -0
  29. data/lib/rbbt/util/misc.rb +296 -285
  30. data/lib/rbbt/util/open.rb +9 -2
  31. data/lib/rbbt/util/persistence.rb +1 -1
  32. data/lib/rbbt/util/task/job.rb +3 -1
  33. data/lib/rbbt/workflow.rb +193 -0
  34. data/lib/rbbt/workflow/accessor.rb +249 -0
  35. data/lib/rbbt/workflow/annotate.rb +60 -0
  36. data/lib/rbbt/workflow/soap.rb +100 -0
  37. data/lib/rbbt/workflow/step.rb +102 -0
  38. data/lib/rbbt/workflow/task.rb +76 -0
  39. data/test/rbbt/resource/test_path.rb +12 -0
  40. data/test/rbbt/test_annotations.rb +106 -0
  41. data/test/rbbt/{util/test_fix_width_table.rb → test_fix_width_table.rb} +8 -9
  42. data/test/rbbt/test_resource.rb +66 -0
  43. data/test/rbbt/test_tsv.rb +332 -0
  44. data/test/rbbt/test_workflow.rb +102 -0
  45. data/test/rbbt/tsv/test_accessor.rb +163 -0
  46. data/test/rbbt/{util/tsv → tsv}/test_attach.rb +86 -43
  47. data/test/rbbt/{util/tsv/test_filters.rb → tsv/test_filter.rb} +31 -13
  48. data/test/rbbt/tsv/test_index.rb +284 -0
  49. data/test/rbbt/{util/tsv → tsv}/test_manipulate.rb +35 -105
  50. data/test/rbbt/util/test_R.rb +1 -1
  51. data/test/rbbt/util/test_chain_methods.rb +22 -0
  52. data/test/rbbt/util/test_filecache.rb +0 -1
  53. data/test/rbbt/util/test_misc.rb +97 -79
  54. data/test/rbbt/util/test_open.rb +1 -0
  55. data/test/rbbt/util/test_tmpfile.rb +1 -1
  56. data/test/rbbt/workflow/test_soap.rb +103 -0
  57. data/test/rbbt/workflow/test_step.rb +142 -0
  58. data/test/rbbt/workflow/test_task.rb +84 -0
  59. data/test/test_helper.rb +7 -7
  60. metadata +80 -54
  61. data/lib/rbbt/util/rake.rb +0 -176
  62. data/lib/rbbt/util/resource.rb +0 -355
  63. data/lib/rbbt/util/task.rb +0 -183
  64. data/lib/rbbt/util/tc_hash.rb +0 -324
  65. data/lib/rbbt/util/tsv.rb +0 -236
  66. data/lib/rbbt/util/tsv/accessor.rb +0 -312
  67. data/lib/rbbt/util/tsv/attach.rb +0 -416
  68. data/lib/rbbt/util/tsv/index.rb +0 -419
  69. data/lib/rbbt/util/tsv/manipulate.rb +0 -300
  70. data/lib/rbbt/util/tsv/misc.rb +0 -41
  71. data/lib/rbbt/util/tsv/parse.rb +0 -324
  72. data/lib/rbbt/util/tsv/resource.rb +0 -88
  73. data/lib/rbbt/util/workflow.rb +0 -135
  74. data/lib/rbbt/util/workflow/soap.rb +0 -116
  75. data/test/rbbt/util/test_persistence.rb +0 -201
  76. data/test/rbbt/util/test_rake.rb +0 -54
  77. data/test/rbbt/util/test_resource.rb +0 -77
  78. data/test/rbbt/util/test_task.rb +0 -133
  79. data/test/rbbt/util/test_tc_hash.rb +0 -144
  80. data/test/rbbt/util/test_tsv.rb +0 -221
  81. data/test/rbbt/util/test_workflow.rb +0 -135
  82. data/test/rbbt/util/tsv/test_accessor.rb +0 -150
  83. data/test/rbbt/util/tsv/test_index.rb +0 -241
  84. data/test/rbbt/util/tsv/test_parse.rb +0 -87
  85. data/test/rbbt/util/tsv/test_resource.rb +0 -9
data/README.rdoc ADDED
@@ -0,0 +1,65 @@
1
+ = Install
2
+
3
+ 1 - install rvm: https://rvm.beginrescueend.com/ (will need git and curl installed)
4
+
5
+ :script
6
+
7
+ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
8
+ cd
9
+ cat .bash_profile > tmp.bash_profile
10
+ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"' >> tmp.bash_profile
11
+ cp .bash_profile .bash_profile.save
12
+ mv tmp.bash_profile .bash_profile
13
+ . .bash_profile
14
+ rvm install 1.8.7
15
+
16
+ 2 - install tokyocabinet (Intructions for user install follow. For system level, make sure we have dev package)
17
+ 1 - download source from http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz
18
+ 2 - unpack and compile using a user-level prefix
19
+ 3 - set LD_RUN_PATH and LD_LIBRARY_PATH to point there
20
+
21
+ :script
22
+
23
+ cd
24
+ mkdir -p tmp/tokyocabinet
25
+ cd tmp/tokyocabinet
26
+ wget "http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz"
27
+ tar xvfz tokyocabinet-1.4.47.tar.gz
28
+ cd tokyocabinet-1.4.47
29
+ ./configure --prefix="$HOME/software/opt/tokyocabinet"
30
+ make
31
+ make install
32
+ cd
33
+ cat .bash_profile > tmp.bash_profile
34
+ echo "export LD_RUN_PATH='$LD_RUN_PATH:$HOME/software/opt/tokyocabinet/lib'" >> tmp.bash_profile
35
+ echo "export LD_LIBRARY_PATH='$LD_LIBRARY_PATH:$HOME/software/opt/tokyocabinet/lib'" >> tmp.bash_profile
36
+ echo "export PATH='$PATH:$HOME/software/opt/tokyocabinet/bin'" >> tmp.bash_profile
37
+ cp .bash_profile .bash_profile.save2
38
+ mv tmp.bash_profile .bash_profile
39
+ . .bash_profile
40
+
41
+ 3 - install gems rbbt-util rbbt-sources rbbt-text rbbt-phgx
42
+
43
+ :script
44
+
45
+ gem install rbbt-util rbbt-sources rbbt-text rbbt-phgx
46
+
47
+ 3.bis - Or install github repos and make ruby use them
48
+
49
+ :script
50
+
51
+ cd
52
+ cd git/
53
+ git clone git://github.com/mikisvaz/rbbt-util.git
54
+ git clone git://github.com/mikisvaz/rbbt-sources.git
55
+ git clone git://github.com/mikisvaz/rbbt-text.git
56
+ git clone git://github.com/mikisvaz/rbbt-phgx.git
57
+ alias druby="env RBBT_LOG=0 ruby $(for d in $HOME/git/rbbt-*;do echo -n "-I$d/lib ";done)"
58
+ alias drake="env RBBT_LOG=0 rake $(for d in $HOME/git/rbbt-*;do echo -n "-I$d/lib ";done)"
59
+
60
+ 4 - Set up R to find the helper lib
61
+
62
+ :script
63
+
64
+ echo "source(system('rbbt_Rutil.rb', intern =T));" >> $HOME/.Rprofile
65
+
data/bin/run_workflow.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rbbt-util'
3
+ require 'rbbt'
4
4
  require 'rbbt/util/simpleopt'
5
- require 'rbbt/util/workflow'
5
+ require 'rbbt/workflow'
6
6
  require 'pp'
7
7
 
8
8
  def usage(task)
@@ -10,12 +10,11 @@ def usage(task)
10
10
  exit -1
11
11
  end
12
12
 
13
- def SOPT_options(task)
13
+ def SOPT_options(workflow, task)
14
14
  sopt_options = []
15
- task.option_summary.flatten.each do |info|
16
- name = info[:name]
15
+ workflow.rec_inputs(task.name).each do |name|
17
16
  short = name.to_s.chars.first
18
- boolean = info[:type] == :boolean
17
+ boolean = workflow.rec_input_types(task.name)[name].to_sym == :boolean
19
18
 
20
19
  sopt_options << "-#{short}--#{name}#{boolean ? '' : '*'}"
21
20
  end
@@ -23,28 +22,54 @@ def SOPT_options(task)
23
22
  sopt_options * ":"
24
23
  end
25
24
 
26
- def fix_options(task, job_options)
27
- option_types = task.option_summary.flatten.inject({}){|types, new| types[new[:name]] = new[:type]; types}
25
+ def fix_options(workflow, task, job_options)
26
+ option_types = workflow.rec_input_types(task.name)
27
+
28
+ workflow.resolve_locals(job_options)
28
29
 
29
30
  job_options_cleaned = {}
30
31
 
31
32
  job_options.each do |name, value|
32
- value = case
33
- when option_types[name] == :float
33
+ value = case option_types[name].to_sym
34
+ when :float
34
35
  value.to_f
35
- when option_types[name] == :integer
36
+ when :integer
36
37
  value.to_i
37
- when option_types[name] == :array
38
- value.split(/[,|]/)
39
- when option_types[name] == :tsv
40
- begin
41
- if value == '-'
42
- TSV.new(STDIN).to_s :sort
38
+ when :string, :text
39
+ case
40
+ when value == '-'
41
+ STDIN.read
42
+ when (String === value and File.exists?(value))
43
+ Open.read(value)
44
+ else
45
+ value
46
+ end
47
+ when :array
48
+ if Array === value
49
+ value
50
+ else
51
+ case
52
+ when value == '-'
53
+ STDIN.read
54
+ when (String === value and File.exists?(value))
55
+ Open.read(value)
43
56
  else
44
- TSV.new(value).to_s :sort
45
- end
46
- rescue
57
+ value
58
+ end.split(/[,|\s]/)
59
+ end
60
+ when :tsv
61
+ if TSV === value
47
62
  value
63
+ else
64
+ begin
65
+ if value == '-'
66
+ TSV.open(STDIN).to_s :sort
67
+ else
68
+ TSV.new(value).to_s :sort
69
+ end
70
+ rescue
71
+ value
72
+ end
48
73
  end
49
74
  else
50
75
  value
@@ -55,64 +80,112 @@ def fix_options(task, job_options)
55
80
  job_options_cleaned
56
81
  end
57
82
 
58
- options = SOPT.get "-t--task*:-l--log*:-h--help:-n--name:-cl--clean:-rcl-recursive_clean"
83
+ options = SOPT.get "-t--task*:-l--log*:-h--help:-n--name*:-cl--clean:-rcl-recursive_clean:-pn--printname:-srv--server"
59
84
 
60
- # Set log, fork, clean, recursive_clean and help
61
- Log.severity = options[:log].to_i if options.include? :log
62
- help = !!options.delete(:help)
63
- do_fork = !!options.delete(:fork)
64
- clean = !!options.delete(:clean)
65
- recursive_clean = !!options.delete(:recursive_clean)
66
-
67
- # Get workflow
68
85
  workflow = ARGV.first
69
- WorkFlow.require_workflow workflow
70
-
71
- # Set task
72
- namespace, task = nil, nil
73
-
74
- case
75
- when (not options[:task])
76
- workflow_usage if help
77
- task = self.last_task
78
- namespace = self
79
- when (options[:task] =~ /\./)
80
- namespace, task = options.delete(:task).split('.')
81
- namespace = Misc.string2const(namespace)
86
+
87
+ if options[:server]
88
+ require 'rbbt/util/log'
89
+ require 'rbbt/workflow'
90
+ require 'rbbt/workflow/rest'
91
+ require 'sinatra'
92
+ require 'compass'
93
+
94
+ Workflow.require_workflow workflow
95
+ WorkflowREST.add_workflows Workflow.workflows.last
96
+
97
+ WorkflowREST.setup
82
98
  else
83
- task_name = options.delete(:task)
84
- task = self.tasks[task_name]
85
- end
86
99
 
87
- usage(task) if help
100
+ # Set log, fork, clean, recursive_clean and help
101
+ Log.severity = options[:log].to_i if options.include? :log
102
+ help = !!options.delete(:help)
103
+ do_fork = !!options.delete(:fork)
104
+ clean = !!options.delete(:clean)
105
+ recursive_clean = !!options.delete(:recursive_clean)
106
+
88
107
 
89
- name = options.delete(:name) || "Default"
108
+ # Get workflow
109
+
110
+ if Rbbt.etc.remote_workflows.exists?
111
+ remote_workflows = Rbbt.etc.remote_workflows.yaml
112
+ else
113
+ remote_workflows = {}
114
+ end
115
+
116
+ if remote_workflows.include? workflow
117
+ require 'rbbt/workflow/rest/client'
118
+ workflow = RbbtRestClient.new remote_workflows[workflow]
119
+ else
120
+ Workflow.require_workflow workflow
121
+ workflow = Workflow.workflows.last
122
+ end
123
+
124
+ # Set task
125
+ namespace, task = nil, nil
126
+
127
+ case
128
+ when (not options[:task])
129
+ usage if help
130
+ task = workflow.last_task
131
+ namespace = workflow
132
+ when (options[:task] =~ /\./)
133
+ namespace, task = options.delete(:task).split('.')
134
+ namespace = Misc.string2const(namespace)
135
+ else
136
+ task_name = options.delete(:task)
137
+ task = workflow.tasks[task_name]
138
+ raise "Task not found: #{ task_name }" if task.nil?
139
+ end
140
+
141
+
142
+ workflow.usage(task) if help
90
143
 
91
- # get job args
92
- sopt_option_string = SOPT_options(task)
93
- job_options = SOPT.get sopt_option_string
94
- job_options = fix_options(task, job_options)
144
+ name = options.delete(:name) || "Default"
95
145
 
96
- #- get job
97
- job = task.job(name, job_options)
146
+ # get job args
147
+ sopt_option_string = SOPT_options(workflow,task)
148
+ job_options = SOPT.get sopt_option_string
149
+ job_options = fix_options(workflow,task, job_options)
98
150
 
99
- # clean job
100
- job.clean if clean
101
- job.recursive_clean if recursive_clean
151
+ #- get job
152
+ job = workflow.job(task.name, name, job_options)
102
153
 
103
- # run
104
- if do_fork
105
- job.fork
106
- while not job.done?
107
- puts "#{job.step}: #{job.messages.last}"
108
- sleep 2
154
+ # clean job
155
+ job.clean if clean
156
+ job.recursive_clean if recursive_clean
157
+
158
+ # run
159
+ if do_fork
160
+ job.fork
161
+ while not job.done?
162
+ Log.debug "#{job.step}: #{job.messages.last}"
163
+ sleep 2
164
+ end
165
+ raise job.messages.last if job.error?
166
+ res = job.load
167
+ else
168
+ res = job.run
109
169
  end
110
- else
111
- job.run
112
- end
113
170
 
114
- #- error
115
- raise job.messages.last if job.error?
171
+ if options.delete(:printname)
172
+ puts job.name
173
+ exit
174
+ else
175
+ Log.low "Job name: #{job.name}"
176
+ end
116
177
 
117
- #print
118
- pp job.load
178
+ #- error
179
+
180
+ #print
181
+ case
182
+ when Array === res
183
+ puts res * "\n"
184
+ when TSV === res
185
+ puts res
186
+ when Hash === res
187
+ puts res.to_yaml
188
+ else
189
+ puts res
190
+ end
191
+ end
data/lib/rbbt-util.rb CHANGED
@@ -3,11 +3,11 @@ require 'rbbt/util/open'
3
3
  require 'rbbt/util/cmd'
4
4
  require 'rbbt/util/tmpfile'
5
5
  require 'rbbt/util/filecache'
6
- require 'rbbt/util/tsv'
7
- require 'rbbt/util/persistence'
6
+ require 'rbbt/tsv'
7
+ require 'rbbt/persist'
8
8
  require 'rbbt/util/misc'
9
9
 
10
10
  FileCache.cachedir = Rbbt.var.cache.filecache.find :user
11
11
  Open.cachedir = Rbbt.var.cache["open-remote"].find :user
12
12
  TmpFile.tmpdir = Rbbt.tmp.find :user
13
- Persistence.cachedir = Rbbt.var.cache.persistence.find :user
13
+ Persist.cachedir = Rbbt.var.cache.persistence.find :user
data/lib/rbbt.rb CHANGED
@@ -1,7 +1,16 @@
1
- require 'rbbt/util/resource'
1
+ require 'rbbt/util/open'
2
+ require 'rbbt/util/tmpfile'
3
+ require 'rbbt/util/filecache'
4
+ require 'rbbt/tsv'
5
+ require 'rbbt/persist'
6
+ require 'rbbt/resource'
2
7
 
3
8
  module Rbbt
4
9
  extend Resource
5
- end
6
-
10
+ pkgdir = 'rbbt'
7
11
 
12
+ FileCache.cachedir = var.cache.filecache.find :user
13
+ TmpFile.tmpdir = tmp.find :user
14
+ Open.cachedir = var.cache["open-remote"].find :user
15
+ Persist.cachedir = var.cache.persistence.find :user
16
+ end
@@ -0,0 +1,215 @@
1
+ require 'rbbt/util/chain_methods'
2
+ require 'json'
3
+ module Annotated
4
+ attr_accessor :annotation_types
5
+
6
+ def self.extended(base)
7
+ base.annotation_types ||= []
8
+ end
9
+
10
+ def annotations
11
+ annotation_types.collect do |mod|
12
+ mod.annotations
13
+ end.flatten.uniq
14
+ end
15
+
16
+ def info
17
+ hash = {:annotation_types => annotation_types}
18
+ annotations.each do |annotation|
19
+ value = self.send(annotation)
20
+ hash[annotation] = value unless value.nil?
21
+ end
22
+ hash
23
+ end
24
+
25
+ def id
26
+ Misc.hash2md5 info
27
+ end
28
+
29
+ def self.load(object, info)
30
+ annotation_types = info[:annotation_types]
31
+ annotation_types.each do |mod|
32
+ mod = Misc.string2const(mod) if String === mod
33
+ mod.setup_info(object, info)
34
+ end
35
+
36
+ object
37
+ end
38
+
39
+ def tsv_values(*fields)
40
+ fields = fields.flatten
41
+ info = self.info
42
+ values = []
43
+ fields.each do |field|
44
+ values << case
45
+ when field == "JSON"
46
+ info.to_json
47
+ when field == "literal"
48
+ self.gsub(/\n|\t/, ' ')
49
+ when info.include?(field.to_sym)
50
+ info.delete(field.to_sym)
51
+ when self.respond_to?(field)
52
+ self.send(field)
53
+ end
54
+ end
55
+ values
56
+ end
57
+
58
+ def self.load_tsv_values(id, values, *fields)
59
+ fields = fields.flatten
60
+ info = {}
61
+ literal_pos = fields.index "literal"
62
+
63
+ object = if literal_pos.nil?
64
+ id
65
+ else
66
+ v = values[literal_pos]
67
+ v = v.first if Array === v
68
+ v
69
+ end
70
+
71
+ fields.each_with_index do |field,i|
72
+ if field == "JSON"
73
+ JSON.parse(values[i]).each do |key, value|
74
+ info[key.to_sym] = value
75
+ end
76
+ else
77
+ info[field.to_sym] = values[i]
78
+ end
79
+ end
80
+
81
+ self.load(object, info)
82
+ end
83
+
84
+ def self.tsv(annotations, *fields)
85
+ fields = case
86
+ when ((fields.compact.empty?) and not annotations.empty?)
87
+ fields = annotations.first.annotations
88
+ fields << :annotation_types
89
+ when (fields == [:literal] and not annotations.empty?)
90
+ fields = annotations.first.annotations
91
+ fields << :literal
92
+ when (fields == [:all] and not annotations.empty?)
93
+ fields = [:annotation_types] + annotations.first.annotations
94
+ fields << :literal
95
+ else
96
+ fields.flatten
97
+ end
98
+ fields = fields.collect{|f| f.to_s}
99
+
100
+ tsv = TSV.setup({}, :key_field => "ID", :fields => fields)
101
+
102
+ annotations.each do |annotation|
103
+ tsv[annotation.id] = annotation.tsv_values(fields)
104
+ end
105
+
106
+ tsv
107
+ end
108
+
109
+ def self.load_tsv(tsv)
110
+ tsv.collect do |id, values|
111
+ Annotated.load_tsv_values(id, values, tsv.fields)
112
+ end
113
+ end
114
+ end
115
+
116
+
117
+ module Annotation
118
+ def self.extended(base)
119
+ if not base.respond_to? :annotations
120
+ class << base
121
+ attr_accessor :annotations, :inheritance, :all_inheritance, :all_annotations
122
+ self
123
+ end
124
+
125
+ base.annotations = []
126
+ base.inheritance = []
127
+ base.all_annotations = []
128
+ base.all_inheritance = []
129
+
130
+ base.module_eval do
131
+ def self.extended(object)
132
+ object.extend Annotated
133
+ if not object.annotation_types.include? self
134
+ object.annotation_types.concat self.inheritance
135
+ object.annotation_types << self
136
+ object.annotation_types.uniq!
137
+ end
138
+ end
139
+
140
+ def self.included(base)
141
+ base.inheritance << self
142
+ base.all_inheritance.concat self.all_inheritance if self.respond_to? :all_inheritance
143
+ base.all_inheritance << self
144
+ base.all_inheritance.uniq!
145
+ base.update_annotations
146
+ end
147
+ end
148
+
149
+ end
150
+ end
151
+
152
+ def update_annotations
153
+ @all_annotations = all_inheritance.inject([]){|acc,mod| acc.concat mod.annotations}.concat(@annotations)
154
+ end
155
+
156
+ def annotation(*values)
157
+ @annotations.concat values.collect{|v| v.to_sym}
158
+ update_annotations
159
+
160
+ module_eval do
161
+ attr_accessor *values
162
+ end
163
+ end
164
+
165
+ def setup_info(object, info)
166
+ object.extend self
167
+ all_annotations.each do |annotation|
168
+ object.send(annotation.to_s + '=', info[annotation])
169
+ end
170
+ end
171
+
172
+ def setup(object, *values)
173
+ object.extend self
174
+
175
+ all_annotations.zip(values).each do |name, value|
176
+ object.send(name.to_s + '=', value)
177
+ end
178
+
179
+ object
180
+ end
181
+ end
182
+
183
+ module AnnotatedArray
184
+ extend ChainMethods
185
+ self.chain_prefix = :annotated_array
186
+
187
+ def annotated_array_get_brackets(pos)
188
+ value = annotated_array_clean_get_brackets(pos)
189
+ annotation_types.each do |mod|
190
+ mod.setup(value, *info.values_at(*mod.annotations))
191
+ end
192
+ value
193
+ end
194
+
195
+ def annotated_array_each
196
+ annotation_array_clean_each do |value|
197
+ annotation_types.each do |mod|
198
+ mod.setup(value, annotation)
199
+ end
200
+ yield value
201
+ end
202
+ end
203
+
204
+ def annotated_array_collect
205
+ annotation_array_clean_collect do |value|
206
+ annotation_types.each do |mod|
207
+ mod.setup(value, annotation)
208
+ end
209
+ yield value
210
+ end
211
+ end
212
+
213
+ end
214
+
215
+