rbbt-util 4.0.2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -0
- data/lib/rbbt/annotations.rb +147 -10
- data/lib/rbbt/persist.rb +5 -1
- data/lib/rbbt/persist/tsv.rb +4 -3
- data/lib/rbbt/resource/path.rb +8 -1
- data/lib/rbbt/tsv.rb +3 -2
- data/lib/rbbt/tsv/accessor.rb +140 -51
- data/lib/rbbt/tsv/attach/util.rb +124 -106
- data/lib/rbbt/tsv/filter.rb +4 -2
- data/lib/rbbt/tsv/manipulate.rb +68 -13
- data/lib/rbbt/tsv/parser.rb +110 -20
- data/lib/rbbt/tsv/serializers.rb +6 -0
- data/lib/rbbt/tsv/util.rb +35 -1
- data/lib/rbbt/util/chain_methods.rb +25 -10
- data/lib/rbbt/util/misc.rb +109 -27
- data/lib/rbbt/util/open.rb +15 -4
- data/lib/rbbt/workflow.rb +18 -3
- data/lib/rbbt/workflow/annotate.rb +6 -1
- data/lib/rbbt/workflow/soap.rb +1 -1
- data/lib/rbbt/workflow/step.rb +13 -3
- data/lib/rbbt/workflow/task.rb +2 -2
- data/share/install/software/lib/install_helpers +6 -0
- data/share/lib/R/util.R +6 -1
- data/test/rbbt/test_annotations.rb +7 -0
- data/test/rbbt/test_persist.rb +32 -0
- data/test/rbbt/test_tsv.rb +101 -2
- data/test/rbbt/test_workflow.rb +11 -0
- data/test/rbbt/tsv/test_accessor.rb +15 -0
- data/test/rbbt/tsv/test_attach.rb +1 -1
- data/test/rbbt/tsv/test_manipulate.rb +37 -3
- data/test/rbbt/tsv/test_util.rb +25 -0
- data/test/rbbt/util/test_misc.rb +8 -0
- metadata +7 -4
- data/lib/rbbt/util/persistence.rb +0 -406
data/README.rdoc
CHANGED
@@ -63,3 +63,10 @@
|
|
63
63
|
|
64
64
|
echo "source(system('rbbt_Rutil.rb', intern =T));" >> $HOME/.Rprofile
|
65
65
|
|
66
|
+
5 - If you plan to run workflows you might want to redefine the default directory to place your workflows (~/.workflows)
|
67
|
+
|
68
|
+
:script
|
69
|
+
|
70
|
+
mkdir -p ~/git/workflows
|
71
|
+
echo "~/git/workflows/" > ~/.rbbt/etc/workflow_dir
|
72
|
+
|
data/lib/rbbt/annotations.rb
CHANGED
@@ -2,6 +2,8 @@ require 'rbbt/util/chain_methods'
|
|
2
2
|
require 'json'
|
3
3
|
module Annotated
|
4
4
|
attr_accessor :annotation_types
|
5
|
+
attr_accessor :context
|
6
|
+
attr_accessor :container
|
5
7
|
|
6
8
|
def self.extended(base)
|
7
9
|
base.annotation_types ||= []
|
@@ -23,7 +25,7 @@ module Annotated
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def id
|
26
|
-
Misc.hash2md5 info
|
28
|
+
Misc.hash2md5 info.merge :self => self
|
27
29
|
end
|
28
30
|
|
29
31
|
def self.load(object, info)
|
@@ -97,7 +99,7 @@ module Annotated
|
|
97
99
|
end
|
98
100
|
fields = fields.collect{|f| f.to_s}
|
99
101
|
|
100
|
-
tsv = TSV.setup({}, :key_field => "ID", :fields => fields)
|
102
|
+
tsv = TSV.setup({}, :key_field => "ID", :fields => fields, :type => :list )
|
101
103
|
|
102
104
|
annotations.each do |annotation|
|
103
105
|
tsv[annotation.id] = annotation.tsv_values(fields)
|
@@ -111,6 +113,15 @@ module Annotated
|
|
111
113
|
Annotated.load_tsv_values(id, values, tsv.fields)
|
112
114
|
end
|
113
115
|
end
|
116
|
+
|
117
|
+
def make_list
|
118
|
+
new = [self]
|
119
|
+
annotation_types.each do |mod|
|
120
|
+
mod.setup(new, *info.values_at(*mod.annotations))
|
121
|
+
end
|
122
|
+
new.context = self.context
|
123
|
+
new
|
124
|
+
end
|
114
125
|
end
|
115
126
|
|
116
127
|
|
@@ -177,13 +188,13 @@ module Annotation
|
|
177
188
|
def setup(object, *values)
|
178
189
|
object.extend self
|
179
190
|
|
180
|
-
|
191
|
+
inputs = Misc.positional2hash(all_annotations, *values)
|
192
|
+
inputs.each do |name, value|
|
181
193
|
object.send(name.to_s + '=', value)
|
182
194
|
end
|
183
195
|
|
184
196
|
object
|
185
197
|
end
|
186
|
-
|
187
198
|
end
|
188
199
|
|
189
200
|
module AnnotatedArray
|
@@ -195,25 +206,60 @@ module AnnotatedArray
|
|
195
206
|
annotation_types.each do |mod|
|
196
207
|
mod.setup(value, *info.values_at(*mod.annotations))
|
197
208
|
end
|
209
|
+
value.context = self.context
|
210
|
+
value.container = self
|
198
211
|
value
|
199
212
|
end
|
200
213
|
|
201
214
|
def annotated_array_each
|
202
215
|
annotated_array_clean_each do |value|
|
203
216
|
annotation_types.each do |mod|
|
204
|
-
mod.setup(value,
|
217
|
+
mod.setup(value, info)
|
205
218
|
end
|
219
|
+
value.context = self.context
|
220
|
+
value.container = self
|
206
221
|
yield value
|
207
222
|
end
|
208
223
|
end
|
209
224
|
|
210
225
|
def annotated_array_collect
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
yield value
|
226
|
+
res = []
|
227
|
+
|
228
|
+
annotated_array_each do |value|
|
229
|
+
res << yield(value)
|
216
230
|
end
|
231
|
+
|
232
|
+
res
|
233
|
+
end
|
234
|
+
|
235
|
+
def annotated_array_select
|
236
|
+
res = []
|
237
|
+
annotated_array_each do |value|
|
238
|
+
res << value if yield(value)
|
239
|
+
end
|
240
|
+
|
241
|
+
annotation_types.each do |mod|
|
242
|
+
mod.setup(res, *info.values_at(*mod.annotations))
|
243
|
+
end
|
244
|
+
res.context = self.context
|
245
|
+
res.container = self.container
|
246
|
+
|
247
|
+
res
|
248
|
+
end
|
249
|
+
|
250
|
+
def annotated_array_reject
|
251
|
+
res = []
|
252
|
+
annotated_array_each do |value|
|
253
|
+
res << value unless yield(value)
|
254
|
+
end
|
255
|
+
|
256
|
+
annotation_types.each do |mod|
|
257
|
+
mod.setup(res, *info.values_at(*mod.annotations))
|
258
|
+
end
|
259
|
+
res.context = self.context
|
260
|
+
res.container = self.container
|
261
|
+
|
262
|
+
res
|
217
263
|
end
|
218
264
|
|
219
265
|
def annotated_array_subset(list)
|
@@ -221,6 +267,97 @@ module AnnotatedArray
|
|
221
267
|
annotation_types.each do |mod|
|
222
268
|
mod.setup(value, *info.values_at(*mod.annotations))
|
223
269
|
end
|
270
|
+
value.context = self.context
|
271
|
+
value.container = self.container
|
272
|
+
value
|
273
|
+
end
|
274
|
+
|
275
|
+
def annotated_array_remove(list)
|
276
|
+
value = (self - list)
|
277
|
+
annotation_types.each do |mod|
|
278
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
279
|
+
end
|
280
|
+
value.context = self.context
|
281
|
+
value.container = self.container
|
282
|
+
value
|
283
|
+
end
|
284
|
+
|
285
|
+
def annotated_array_uniq
|
286
|
+
value = self.annotated_array_clean_uniq
|
287
|
+
|
288
|
+
annotation_types.each do |mod|
|
289
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
290
|
+
end
|
291
|
+
|
292
|
+
value.context = self.context
|
293
|
+
value.container = self.container
|
294
|
+
value
|
295
|
+
end
|
296
|
+
def annotated_array_flatten
|
297
|
+
value = self.annotated_array_clean_flatten.dup
|
298
|
+
|
299
|
+
annotation_types.each do |mod|
|
300
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
301
|
+
end
|
302
|
+
|
303
|
+
value.context = self.context
|
304
|
+
value.container = self.container
|
305
|
+
value
|
306
|
+
end
|
307
|
+
|
308
|
+
def annotated_array_reverse
|
309
|
+
value = self.annotated_array_clean_reverse
|
310
|
+
annotation_types.each do |mod|
|
311
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
312
|
+
end
|
313
|
+
value.context = self.context
|
314
|
+
value.container = self.container
|
315
|
+
value
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
def annotated_array_sort_by(&block)
|
320
|
+
value = self.annotated_array_clean_sort_by &block
|
321
|
+
annotation_types.each do |mod|
|
322
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
323
|
+
end
|
324
|
+
value.context = self.context
|
325
|
+
value.container = self.container
|
326
|
+
value
|
327
|
+
end
|
328
|
+
|
329
|
+
def annotated_array_sort
|
330
|
+
value = self.annotated_array_clean_sort
|
331
|
+
|
332
|
+
annotation_types.each do |mod|
|
333
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
334
|
+
end
|
335
|
+
value.context = self.context
|
336
|
+
value.container = self.container
|
337
|
+
value
|
338
|
+
end
|
339
|
+
|
340
|
+
def annotated_array_select_by(method)
|
341
|
+
case
|
342
|
+
when (Symbol === method or String === method)
|
343
|
+
method = self.send(method)
|
344
|
+
when Array === method
|
345
|
+
method = method.dup
|
346
|
+
else
|
347
|
+
raise "Unknown format of method: of class #{method.class}"
|
348
|
+
end
|
349
|
+
|
350
|
+
value = []
|
351
|
+
|
352
|
+
self.annotated_array_clean_each do |e|
|
353
|
+
value << e if method.shift
|
354
|
+
end
|
355
|
+
|
356
|
+
#annotation_types.each do |mod|
|
357
|
+
# mod.setup(value, *info.values_at(*mod.annotations))
|
358
|
+
#end
|
359
|
+
#value.context = self.context
|
360
|
+
#value.container = self.container
|
224
361
|
value
|
225
362
|
end
|
226
363
|
end
|
data/lib/rbbt/persist.rb
CHANGED
@@ -119,7 +119,11 @@ module Persist
|
|
119
119
|
when :string, :text
|
120
120
|
Open.write(path, content)
|
121
121
|
when :array
|
122
|
-
|
122
|
+
if content.any?
|
123
|
+
Open.write(path, content * "\n" + "\n")
|
124
|
+
else
|
125
|
+
Open.write(path, "")
|
126
|
+
end
|
123
127
|
when :marshal_tsv
|
124
128
|
Open.write(path, Marshal.dump(content.dup))
|
125
129
|
when :marshal
|
data/lib/rbbt/persist/tsv.rb
CHANGED
@@ -83,7 +83,7 @@ module Persist
|
|
83
83
|
database.persistence_path ||= path
|
84
84
|
|
85
85
|
TSV.setup database
|
86
|
-
database.serializer = serializer
|
86
|
+
database.serializer = serializer || database.serializer
|
87
87
|
|
88
88
|
database
|
89
89
|
end
|
@@ -100,6 +100,7 @@ module Persist
|
|
100
100
|
filename ||= source.object_id.to_s
|
101
101
|
|
102
102
|
path = persistence_path(filename, persist_options, options)
|
103
|
+
|
103
104
|
if is_persisted? path
|
104
105
|
Log.debug "TSV persistence up-to-date: #{ path }"
|
105
106
|
return open_tokyocabinet(path, false)
|
@@ -109,8 +110,8 @@ module Persist
|
|
109
110
|
|
110
111
|
FileUtils.rm path if File.exists? path
|
111
112
|
|
112
|
-
data = open_tokyocabinet(path, true)
|
113
|
-
data.serializer = :type
|
113
|
+
data = open_tokyocabinet(path, true, persist_options[:serializer])
|
114
|
+
data.serializer = :type unless data.serializer
|
114
115
|
data
|
115
116
|
else
|
116
117
|
data = {}
|
data/lib/rbbt/resource/path.rb
CHANGED
@@ -133,6 +133,14 @@ module Path
|
|
133
133
|
TSV.open(self.produce, *args)
|
134
134
|
end
|
135
135
|
|
136
|
+
def list
|
137
|
+
Open.read(self.produce.find).split "\n"
|
138
|
+
end
|
139
|
+
|
140
|
+
def keys(field = 0, sep = "\t")
|
141
|
+
Open.read(self.produce.find).split("\n").collect{|l| next if l =~ /^#/; l.split(sep, -1)[field]}.compact
|
142
|
+
end
|
143
|
+
|
136
144
|
def yaml
|
137
145
|
YAML.load self.open
|
138
146
|
end
|
@@ -149,7 +157,6 @@ module Path
|
|
149
157
|
TSV.pos_index(self.produce.find, pos, options)
|
150
158
|
end
|
151
159
|
|
152
|
-
|
153
160
|
def to_yaml(*args)
|
154
161
|
self.to_s.to_yaml(*args)
|
155
162
|
end
|
data/lib/rbbt/tsv.rb
CHANGED
@@ -90,12 +90,14 @@ module TSV
|
|
90
90
|
data.serializer = case
|
91
91
|
when parser.cast.nil?
|
92
92
|
data.serializer = parser.type
|
93
|
-
when (parser.cast == :to_i and parser.type == :list)
|
93
|
+
when (parser.cast == :to_i and (parser.type == :list or parser.type == :flat))
|
94
94
|
data.serializer = :integer_array
|
95
95
|
when (parser.cast == :to_i and parser.type == :single)
|
96
96
|
data.serializer = :integer
|
97
97
|
when (parser.cast == :to_f and parser.type == :single)
|
98
98
|
data.serializer = :float
|
99
|
+
when (parser.cast == :to_f and (parser.type == :list or parser.type == :flat))
|
100
|
+
data.serializer = :float_array
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
@@ -119,7 +121,6 @@ module TSV
|
|
119
121
|
|
120
122
|
while not line.nil?
|
121
123
|
begin
|
122
|
-
|
123
124
|
progress_monitor.tick(stream.pos) if progress_monitor
|
124
125
|
|
125
126
|
line = parser.process line
|
data/lib/rbbt/tsv/accessor.rb
CHANGED
@@ -4,7 +4,7 @@ module TSV
|
|
4
4
|
extend ChainMethods
|
5
5
|
self.chain_prefix = :tsv
|
6
6
|
|
7
|
-
attr_accessor :unnamed
|
7
|
+
attr_accessor :unnamed, :serializer_module
|
8
8
|
|
9
9
|
def with_unnamed
|
10
10
|
saved_unnamed = @unnamed
|
@@ -47,6 +47,13 @@ module TSV
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
if not data.respond_to? :serialized_get
|
52
|
+
class << data
|
53
|
+
alias serialized_get tsv_clean_get_brackets
|
54
|
+
alias serialized_set tsv_clean_set_brackets
|
55
|
+
end
|
56
|
+
end
|
50
57
|
end
|
51
58
|
|
52
59
|
KEY_PREFIX = "__tsv_hash_"
|
@@ -54,67 +61,111 @@ module TSV
|
|
54
61
|
ENTRIES = []
|
55
62
|
ENTRY_KEYS = []
|
56
63
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
SERIALIZER_ALIAS[serializer.to_sym].load(serialized_value) unless serialized_value.nil?
|
61
|
-
end
|
62
|
-
|
63
|
-
def serialized_set(key, value)
|
64
|
-
raise "Uninitialized serializer" if serializer == :type
|
65
|
-
if value.nil?
|
66
|
-
tsv_clean_set_brackets(key, nil)
|
67
|
-
else
|
68
|
-
tsv_clean_set_brackets(key, SERIALIZER_ALIAS[serializer.to_sym].dump(value))
|
69
|
-
end
|
64
|
+
#{{{ Chained Methods
|
65
|
+
def tsv_empty?
|
66
|
+
length == 0
|
70
67
|
end
|
71
68
|
|
72
|
-
#{{{ Chained Methods
|
73
69
|
def tsv_get_brackets(key)
|
74
|
-
value =
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
70
|
+
value = serialized_get(key)
|
71
|
+
return value if @unnamed or fields.nil?
|
72
|
+
|
73
|
+
case type
|
74
|
+
when :double, :list
|
75
|
+
NamedArray.setup value, fields, key
|
76
|
+
when :flat, :single
|
77
|
+
Entity.formats[fields.first].setup(value, :format => fields.first) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
78
|
+
end
|
81
79
|
value
|
82
80
|
end
|
83
81
|
|
84
82
|
def tsv_set_brackets(key,value)
|
85
|
-
|
86
|
-
tsv_clean_set_brackets(key, value)
|
87
|
-
else
|
88
|
-
serialized_set(key, value)
|
89
|
-
end
|
83
|
+
serialized_set(key, value)
|
90
84
|
end
|
91
85
|
|
92
86
|
def tsv_keys
|
93
|
-
tsv_clean_keys - ENTRY_KEYS
|
87
|
+
keys = tsv_clean_keys - ENTRY_KEYS
|
88
|
+
return keys if @unnamed or key_field.nil?
|
89
|
+
|
90
|
+
if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
91
|
+
Entity.formats[key_field].setup(keys.collect{|k| k.dup}, :format => key_field)
|
92
|
+
else
|
93
|
+
keys
|
94
|
+
end
|
94
95
|
end
|
95
96
|
|
96
97
|
def tsv_values
|
97
98
|
values = values_at(*keys)
|
98
|
-
values
|
99
|
+
return values if @unnamed or fields.nil?
|
100
|
+
|
101
|
+
case type
|
102
|
+
when :double, :list
|
103
|
+
values.each{|value| NamedArray.setup value, fields }
|
104
|
+
when :flat, :single
|
105
|
+
values.each{|value|
|
106
|
+
Entity.formats[fields.first].setup(value, :format => fields.first)
|
107
|
+
} if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
108
|
+
end
|
109
|
+
|
99
110
|
values
|
100
111
|
end
|
101
112
|
|
102
113
|
def tsv_each
|
114
|
+
fields = self.fields
|
115
|
+
|
116
|
+
serializer = self.serializer
|
117
|
+
serializer_module = SERIALIZER_ALIAS[serializer] unless serializer.nil?
|
103
118
|
tsv_clean_each do |key, value|
|
104
119
|
next if ENTRY_KEYS.include? key
|
105
120
|
|
106
|
-
|
107
|
-
|
121
|
+
# TODO Update this to be more efficient
|
122
|
+
value = serializer_module.load(value) unless serializer.nil?
|
123
|
+
|
124
|
+
# Annotated with Entity and NamedArray
|
125
|
+
if not @unnamed
|
126
|
+
if not fields.nil?
|
127
|
+
case type
|
128
|
+
when :double, :list
|
129
|
+
NamedArray.setup value, fields, key if Array === value
|
130
|
+
when :flat, :single
|
131
|
+
Entity.formats[fields.first].setup(value, :format => fields.first) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
132
|
+
end
|
133
|
+
end
|
134
|
+
if defined?(Entity) and not key_field.nil? and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
135
|
+
key = Entity.formats[key_field].setup(key.dup, :format => key_field)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
108
139
|
yield key, value if block_given?
|
109
140
|
[key, value]
|
110
141
|
end
|
111
142
|
end
|
112
143
|
|
113
144
|
def tsv_collect
|
145
|
+
serializer = self.serializer
|
146
|
+
serializer_module = SERIALIZER_ALIAS[serializer] unless serializer.nil?
|
114
147
|
tsv_clean_collect do |key, value|
|
115
148
|
next if ENTRY_KEYS.include? key
|
116
|
-
|
117
|
-
|
149
|
+
|
150
|
+
# TODO Update this to be more efficient
|
151
|
+
value = serializer_module.load(value) unless serializer.nil?
|
152
|
+
|
153
|
+
# Annotated with Entity and NamedArray
|
154
|
+
if not @unnamed
|
155
|
+
if not fields.nil?
|
156
|
+
case type
|
157
|
+
when :double, :list
|
158
|
+
NamedArray.setup value, fields, key if Array === value
|
159
|
+
when :flat, :single
|
160
|
+
Entity.formats[fields.first].setup(value, :format => fields.first) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
161
|
+
end
|
162
|
+
end
|
163
|
+
if defined?(Entity) and not key_field.nil? and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
164
|
+
key = Entity.formats[key_field].setup(key.dup, :format => key_field)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
118
169
|
if block_given?
|
119
170
|
yield key, value
|
120
171
|
else
|
@@ -229,9 +280,42 @@ def #{ entry }
|
|
229
280
|
@#{entry}
|
230
281
|
end
|
231
282
|
|
232
|
-
|
233
|
-
|
234
|
-
|
283
|
+
|
284
|
+
if '#{entry}' == 'serializer'
|
285
|
+
|
286
|
+
def #{ entry }=(value)
|
287
|
+
@#{entry} = value
|
288
|
+
self.tsv_clean_set_brackets '#{key}', value.to_yaml
|
289
|
+
|
290
|
+
return if value.nil?
|
291
|
+
|
292
|
+
self.serializer_module = SERIALIZER_ALIAS[value.to_sym]
|
293
|
+
|
294
|
+
if serializer_module.nil?
|
295
|
+
class << self
|
296
|
+
alias serialized_get tsv_clean_get_brackets
|
297
|
+
alias serialized_set tsv_clean_set_brackets
|
298
|
+
end
|
299
|
+
|
300
|
+
else
|
301
|
+
class << self
|
302
|
+
|
303
|
+
define_method :serialized_get do |key|
|
304
|
+
self.serializer_module.load(tsv_clean_get_brackets(key))
|
305
|
+
end
|
306
|
+
|
307
|
+
define_method :serialized_set do |key, value|
|
308
|
+
tsv_clean_set_brackets key, self.serializer_module.dump(value)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
end
|
314
|
+
else
|
315
|
+
def #{ entry }=(value)
|
316
|
+
@#{entry} = value
|
317
|
+
self.tsv_clean_set_brackets '#{key}', value.to_yaml
|
318
|
+
end
|
235
319
|
end
|
236
320
|
"
|
237
321
|
end
|
@@ -323,27 +407,26 @@ end
|
|
323
407
|
|
324
408
|
str = ""
|
325
409
|
|
326
|
-
str << "#: " << Misc.hash2string(ENTRIES.collect{|key| [key.to_sym, self.send(key)]}) << "\n" unless no_options
|
410
|
+
str << "#: " << Misc.hash2string((ENTRIES - ["key_field", "fields"]).collect{|key| [key.to_sym, self.send(key)]}) << "\n" unless no_options
|
327
411
|
if fields
|
328
412
|
str << "#" << key_field << "\t" << fields * "\t" << "\n"
|
329
413
|
end
|
330
414
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
415
|
+
with_unnamed do
|
416
|
+
if keys.nil?
|
417
|
+
each do |key, values|
|
418
|
+
key = key.to_s if Symbol === key
|
419
|
+
str << key.to_s
|
420
|
+
str << values_to_s(values)
|
421
|
+
end
|
422
|
+
else
|
423
|
+
keys.zip(values_at(*keys)).each do |key, values|
|
424
|
+
key = key.to_s if Symbol === key
|
425
|
+
str << key.to_s << values_to_s(values)
|
426
|
+
end
|
343
427
|
end
|
344
|
-
end
|
345
428
|
|
346
|
-
|
429
|
+
end
|
347
430
|
str
|
348
431
|
end
|
349
432
|
|
@@ -352,5 +435,11 @@ end
|
|
352
435
|
keys[0..10].zip(values[0..10]).each do |k,v| peek[k] = v end
|
353
436
|
peek
|
354
437
|
end
|
438
|
+
|
439
|
+
def to_hash
|
440
|
+
new = self.dup
|
441
|
+
ENTRY_KEYS.each{|entry| new.delete entry}
|
442
|
+
new
|
443
|
+
end
|
355
444
|
end
|
356
445
|
|