rbbt-util 4.0.2 → 4.1.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 +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
|
|