rbbt-util 4.1.0 → 4.2.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.
@@ -88,7 +88,7 @@ module Persist
88
88
  database
89
89
  end
90
90
 
91
- def self.persist_tsv(source, filename, options, persist_options = {})
91
+ def self.persist_tsv(source, filename, options = {}, persist_options = {})
92
92
  persist_options[:prefix] ||= "TSV"
93
93
 
94
94
  data = case
@@ -181,7 +181,7 @@ module Path
181
181
  if identifier_file_path.nil?
182
182
  []
183
183
  else
184
- [identifier_file_path.nil?]
184
+ [identifier_file_path]
185
185
  end
186
186
  end
187
187
  end
data/lib/rbbt/tsv.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
 
3
3
  require 'rbbt/util/misc'
4
+ require 'rbbt/util/named_array'
4
5
  require 'rbbt/util/log'
5
6
 
6
7
  require 'rbbt/persist'
@@ -38,10 +39,11 @@ module TSV
38
39
 
39
40
  filename = get_filename source
40
41
  serializer = Misc.process_options options, :serializer
42
+ unnamed = Misc.process_options options, :unnamed
41
43
 
42
44
  Log.debug "TSV open: #{ filename } - #{options.inspect}"
43
45
 
44
- Persist.persist_tsv source, filename, options, persist_options do |data|
46
+ data = Persist.persist_tsv source, filename, options, persist_options do |data|
45
47
  if serializer
46
48
  data.extend TSV unless TSV === data
47
49
  data.serializer = serializer
@@ -57,6 +59,10 @@ module TSV
57
59
 
58
60
  data
59
61
  end
62
+
63
+ data.unnamed = unnamed unless unnamed.nil?
64
+
65
+ data
60
66
  end
61
67
 
62
68
  def self.parse_header(stream, options = {})
@@ -68,13 +68,14 @@ module TSV
68
68
 
69
69
  def tsv_get_brackets(key)
70
70
  value = serialized_get(key)
71
- return value if @unnamed or fields.nil?
71
+ return value if value.nil? or @unnamed or fields.nil?
72
72
 
73
73
  case type
74
74
  when :double, :list
75
- NamedArray.setup value, fields, key
75
+ NamedArray.setup value, fields, key, namespace
76
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
77
+ value = value.dup if value.frozen?
78
+ Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
78
79
  end
79
80
  value
80
81
  end
@@ -88,7 +89,7 @@ module TSV
88
89
  return keys if @unnamed or key_field.nil?
89
90
 
90
91
  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
+ Entity.formats[key_field].setup(keys.collect{|k| k.dup}, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field}) )
92
93
  else
93
94
  keys
94
95
  end
@@ -100,10 +101,10 @@ module TSV
100
101
 
101
102
  case type
102
103
  when :double, :list
103
- values.each{|value| NamedArray.setup value, fields }
104
+ values.each{|value| NamedArray.setup value, fields, nil, namespace }
104
105
  when :flat, :single
105
106
  values.each{|value|
106
- Entity.formats[fields.first].setup(value, :format => fields.first)
107
+ Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first}))
107
108
  } if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
108
109
  end
109
110
 
@@ -126,13 +127,13 @@ module TSV
126
127
  if not fields.nil?
127
128
  case type
128
129
  when :double, :list
129
- NamedArray.setup value, fields, key if Array === value
130
+ NamedArray.setup value, fields, key, namespace if Array === value
130
131
  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
+ Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
132
133
  end
133
134
  end
134
135
  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
+ key = Entity.formats[key_field].setup(key.dup, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field}))
136
137
  end
137
138
  end
138
139
 
@@ -155,13 +156,13 @@ module TSV
155
156
  if not fields.nil?
156
157
  case type
157
158
  when :double, :list
158
- NamedArray.setup value, fields, key if Array === value
159
+ NamedArray.setup value, fields, key, namespace if Array === value
159
160
  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
+ Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
161
162
  end
162
163
  end
163
164
  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
+ key = Entity.formats[key_field].setup(key.dup, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field}))
165
166
  end
166
167
  end
167
168
 
@@ -215,13 +216,16 @@ module TSV
215
216
  if not block_given?
216
217
  if fields == :all
217
218
  if just_keys
218
- elems.sort_by{|key, value| key }.collect{|key, values| key}
219
+ keys = elems.sort_by{|key, value| key }.collect{|key, values| key}
220
+ Entity.formats[key_field].setup(keys, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? key_field
219
221
  else
220
222
  elems.sort_by{|key, value| key }
221
223
  end
222
224
  else
223
225
  if just_keys
224
- elems.sort_by{|key, value| value }.collect{|key, value| key}
226
+ keys = elems.sort_by{|key, value| value }.collect{|key, value| key}
227
+ Entity.formats[key_field].setup(keys, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? key_field
228
+ keys
225
229
  else
226
230
  elems.sort_by{|key, value| value }.collect{|key, value| [key, self[key]]}
227
231
  end
@@ -299,8 +303,9 @@ if '#{entry}' == 'serializer'
299
303
 
300
304
  else
301
305
  class << self
302
-
306
+
303
307
  define_method :serialized_get do |key|
308
+ return nil unless self.include? key
304
309
  self.serializer_module.load(tsv_clean_get_brackets(key))
305
310
  end
306
311
 
@@ -335,7 +340,7 @@ end
335
340
  if @fields.nil? or @unnamed
336
341
  @fields
337
342
  else
338
- NamedArray.setup @fields, @fields
343
+ NamedArray.setup @fields, @fields, nil, namespace
339
344
  end
340
345
  end
341
346
 
@@ -235,19 +235,10 @@ module TSV
235
235
 
236
236
  if current_index.nil?
237
237
  current_index = next_file.index(:target => next_key, :fields => [current_key], :persist => persist_input)
238
+ current_index = current_index.select :key => data_file.keys
238
239
  else
239
240
  next_index = next_file.index :target => next_key, :fields => [current_key], :persist => persist_input
240
241
 
241
- if TokyoCabinet::HDB === current_index
242
- tmp = TSV.setup({}, :key_field => current_index.key_field, :fields => [current_index.fields], :serializer => current_index.serializer, :type => current_index.type, :filename => current_index.filename)
243
- current_index.with_unnamed do
244
- current_index.each do |key,value|
245
- tmp.tsv_clean_set_brackets(key, current_index.tsv_clean_get_brackets(key))
246
- end
247
- end
248
- current_index = tmp
249
- end
250
-
251
242
  next_index.with_unnamed do
252
243
  current_index.with_unnamed do
253
244
  current_index.process current_index.fields.first do |values|
@@ -245,6 +245,7 @@ module TSV
245
245
  data.key_field = new_key_field_name
246
246
  data.fields = new_field_names
247
247
  data.filename = filename
248
+ data.namespace = namespace
248
249
  data.type = type
249
250
  end
250
251
  end
@@ -281,9 +282,10 @@ module TSV
281
282
  new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
282
283
 
283
284
  new.key_field = key_field
284
- new.fields = fields.dup
285
+ new.fields = fields.dup unless fields.nil?
285
286
  new.type = type
286
287
  new.filename = filename
288
+ new.namespace = namespace
287
289
 
288
290
  case
289
291
  when (method.nil? and block_given?)
@@ -429,15 +431,31 @@ module TSV
429
431
  end
430
432
 
431
433
  def add_field(name = nil)
434
+ old_monitor = @monitor
435
+ @monitor = {:desc => "Adding field #{ name }"} if TrueClass === monitor
436
+
432
437
  through do |key, values|
433
438
  new_values = yield(key, values)
434
439
  new_values = [new_values] if type == :double and not Array === new_values
435
440
 
436
- values << new_values
441
+ case
442
+ when (values.nil? and (fields.nil? or fields.empty?))
443
+ values = [new_values]
444
+ when values.nil?
445
+ values = [nil] * fields.length + [new_values]
446
+ when NamedArray === values
447
+ values += [new_values]
448
+ else
449
+ values << new_values
450
+ end
437
451
  self[key] = values
438
452
  end
453
+ @monitor = old_monitor
439
454
 
440
- self.fields = self.fields + [name] if fields != nil and name != nil
455
+ if not fields.nil? and not name.nil?
456
+ fields = self.fields + [name]
457
+ self.fields = fields
458
+ end
441
459
 
442
460
  self
443
461
  end
@@ -1,7 +1,7 @@
1
1
  require 'rbbt/util/cmd'
2
2
  module TSV
3
3
  class Parser
4
- attr_accessor :header_hash, :sep, :sep2, :type, :key_position, :field_positions, :cast, :key_field, :fields, :fix, :select, :serializer, :straight, :take_all, :zipped
4
+ attr_accessor :header_hash, :sep, :sep2, :type, :key_position, :field_positions, :cast, :key_field, :fields, :fix, :select, :serializer, :straight, :take_all, :zipped, :namespace
5
5
 
6
6
  class SKIP_LINE < Exception; end
7
7
  class END_PARSING < Exception; end
@@ -62,6 +62,16 @@ module TSV
62
62
  line.split(@sep, -1)
63
63
  end
64
64
 
65
+ def get_values_single_from_flat(parts)
66
+ return parts.shift, parts.first if field_positions.nil? and key_position.nil?
67
+ if key_position == 0
68
+ [parts.shift, parts]
69
+ else
70
+ key = parts.shift
71
+ [parts, [key]]
72
+ end
73
+ end
74
+
65
75
  def get_values_single(parts)
66
76
  return parts.shift, parts.first if field_positions.nil? and key_position.nil?
67
77
  key = parts[key_position]
@@ -287,7 +297,8 @@ module TSV
287
297
  @header_hash = Misc.process_options(options, :header_hash) || "#"
288
298
  @sep = Misc.process_options(options, :sep) || "\t"
289
299
 
290
- options = parse_header(stream).merge options
300
+ header_options = parse_header(stream)
301
+ options = header_options.merge options
291
302
 
292
303
  @type = Misc.process_options(options, :type) || :double
293
304
  merge = Misc.process_options(options, :merge) || false
@@ -298,6 +309,7 @@ module TSV
298
309
  @fix = Misc.process_options(options, :fix)
299
310
  @select= Misc.process_options options, :select
300
311
  @zipped = Misc.process_options options, :zipped
312
+ @namespace = Misc.process_options options, :namespace
301
313
 
302
314
  case @type
303
315
  when :double
@@ -314,9 +326,15 @@ module TSV
314
326
  self.instance_eval do alias add_to_data add_to_data_no_merge_double end
315
327
  end
316
328
  when :single
317
- self.instance_eval do alias get_values get_values_single end
318
- self.instance_eval do alias cast_values cast_values_single end
319
- self.instance_eval do alias add_to_data add_to_data_no_merge_list end
329
+ if header_options[:type] == :flat
330
+ self.instance_eval do alias get_values get_values_single_from_flat end
331
+ self.instance_eval do alias cast_values cast_values_single end
332
+ self.instance_eval do alias add_to_data add_to_data_no_merge_double end
333
+ else
334
+ self.instance_eval do alias get_values get_values_single end
335
+ self.instance_eval do alias cast_values cast_values_single end
336
+ self.instance_eval do alias add_to_data add_to_data_no_merge_list end
337
+ end
320
338
  when :list
321
339
  self.instance_eval do alias get_values get_values_list end
322
340
  self.instance_eval do alias cast_values cast_values_list end
@@ -343,6 +361,7 @@ module TSV
343
361
  data.type = @type
344
362
  data.key_field = @key_field
345
363
  data.fields = @fields
364
+ data.namespace = @namespace
346
365
  data
347
366
  end
348
367
  end
data/lib/rbbt/tsv/util.rb CHANGED
@@ -46,7 +46,7 @@ module TSV
46
46
 
47
47
  path = Persist.persistence_path(filename, persist_options)
48
48
  TmpFile.with_file(values * "\n") do |value_file|
49
- cmd = "cat '#{ path }' | grep -w -F -f '#{ value_file }' |cut -f 2 |sort|uniq -c|sed 's/^ *//;s/ /\\t/'"
49
+ cmd = "cat '#{ path }' | grep -w -F -f '#{ value_file }' |cut -f 2 |sort|uniq -c|sed 's/^ *//;s/ /\t/'"
50
50
  begin
51
51
  TSV.open(CMD.cmd(cmd), :key_field => 1, :type => :single, :cast => :to_i)
52
52
  rescue
@@ -2,6 +2,7 @@ require 'rbbt/util/log'
2
2
  require 'set'
3
3
 
4
4
  module ChainMethods
5
+
5
6
  def self.chain_methods_extended(base)
6
7
  if not base.respond_to? :chain_prefix
7
8
  metaclass = class << base
@@ -14,10 +15,6 @@ module ChainMethods
14
15
  end
15
16
 
16
17
  metaclass.module_eval do
17
- def setup_chain(object)
18
- object.extend self
19
- end
20
-
21
18
  def setup_chains(base)
22
19
  raise "No prefix specified for #{self.to_s}" if self.chain_prefix.nil? or (String === self.chain_prefix and self.chain_prefix.empty?)
23
20
  methods = self.chained_methods
@@ -26,17 +23,6 @@ module ChainMethods
26
23
 
27
24
  prefix = self.chain_prefix
28
25
 
29
- #do_chain = true
30
- #methods.collect{|new_method|
31
- # original = new_method.sub(prefix.to_s + '_', '')
32
- # clean = prefix.to_s + '_clean_' + original
33
- # if base.respond_to? clean
34
- # do_chain = false
35
- # break
36
- # end
37
- #}
38
-
39
-
40
26
  if not base.respond_to?(:processed_chains) or base.processed_chains.nil? or not base.processed_chains.include? prefix
41
27
  class << base
42
28
  attr_accessor :processed_chains
@@ -61,6 +47,7 @@ module ChainMethods
61
47
  alias_method clean_method, original
62
48
  rescue
63
49
  end
50
+
64
51
  alias_method original, new_method
65
52
  end
66
53
  end
@@ -73,17 +60,19 @@ module ChainMethods
73
60
  alias prev_chain_methods_extended extended if methods.include? "extended"
74
61
 
75
62
  def extended(base)
76
- prev_chain_methods_extended(base) if methods.include? "prev_chain_methods_extended"
63
+ if self.respond_to? :prev_chain_methods_extended
64
+ prev_chain_methods_extended(base)
65
+ end
77
66
  setup_chains(base)
78
67
  end
79
68
  end
80
69
  end
81
- end
82
-
83
- base.chain_prefix = base.to_s.downcase.to_sym
84
- end
85
-
86
- def self.extended(base)
87
- chain_methods_extended(base)
88
70
  end
71
+
72
+ base.chain_prefix = base.to_s.downcase.to_sym
73
+ end
74
+
75
+ def self.extended(base)
76
+ chain_methods_extended(base)
77
+ end
89
78
  end
@@ -7,6 +7,65 @@ require 'net/smtp'
7
7
  module Misc
8
8
  class FieldNotFoundError < StandardError;end
9
9
 
10
+ def self.ensembl_server(organism)
11
+ date = organism.split("/")[1]
12
+ if date.nil?
13
+ "www.ensembl.org"
14
+ else
15
+ "#{ date }.archive.ensembl.org"
16
+ end
17
+ end
18
+
19
+ def self.filename?(string)
20
+ String === string and string.length > 0 and string.length < 250 and File.exists?(string)
21
+ end
22
+
23
+ def self.max(list)
24
+ max = nil
25
+ list.each do |v|
26
+ next if v.nil?
27
+ max = v if max.nil? or v > max
28
+ end
29
+ max
30
+ end
31
+
32
+ def self.google_venn(list1, list2, list3, name1 = nil, name2 = nil, name3 = nil, total = nil)
33
+ name1 ||= "list 1"
34
+ name2 ||= "list 2"
35
+ name3 ||= "list 3"
36
+
37
+ sizes = [list1, list2, list3, list1 & list2, list1 & list3, list2 & list3, list1 & list2 & list3].collect{|l| l.length}
38
+
39
+ total = total.length if Array === total
40
+
41
+ label = "#{name1}: #{sizes[0]} (#{name2}: #{sizes[3]}, #{name3}: #{sizes[4]})"
42
+ label << "|#{name2}: #{sizes[1]} (#{name1}: #{sizes[3]}, #{name3}: #{sizes[5]})"
43
+ label << "|#{name3}: #{sizes[2]} (#{name1}: #{sizes[4]}, #{name2}: #{sizes[5]})"
44
+ if total
45
+ label << "| INTERSECTION: #{sizes[6]} TOTAL: #{total}"
46
+ else
47
+ label << "| INTERSECTION: #{sizes[6]}"
48
+ end
49
+
50
+ max = total || sizes.max
51
+ sizes = sizes.collect{|v| (v.to_f/max * 100).to_i.to_f / 100}
52
+ url = "https://chart.googleapis.com/chart?cht=v&chs=500x300&chd=t:#{sizes * ","}&chco=FF6342,ADDE63,63C6DE,FFFFFF&chdl=#{label}"
53
+ end
54
+
55
+ def self.sum(list)
56
+ list.compact.inject(0.0){|acc,e| acc += e}
57
+ end
58
+
59
+ def self.mean(list)
60
+ sum(list) / list.compact.length
61
+ end
62
+
63
+ def self.sd(list)
64
+ return nil if list.length < 3
65
+ mean = mean(list)
66
+ Math.sqrt(list.compact.inject(0.0){|acc,e| d = e - mean; acc += d * d}) / (list.compact.length - 1)
67
+ end
68
+
10
69
  def self.consolidate(list)
11
70
  list.inject(nil){|acc,e|
12
71
  if acc.nil?
@@ -34,7 +93,7 @@ module Misc
34
93
  IndiferentHash.setup(options)
35
94
  options = Misc.add_defaults options, :from_alias => nil, :to_alias => nil, :server => 'localhost', :port => 25, :user => nil, :pass => nil, :auth => :login
36
95
  IndiferentHash.setup(options)
37
-
96
+
38
97
  server, port, user, pass, from_alias, to_alias, auth = Misc.process_options options, :server, :port, :user, :pass, :from_alias, :to_alias, :auth
39
98
 
40
99
  msg = <<-END_OF_MESSAGE
@@ -43,11 +102,11 @@ To: #{to_alias} <#{to}>
43
102
  Subject: #{subject}
44
103
 
45
104
  #{message}
46
- END_OF_MESSAGE
105
+ END_OF_MESSAGE
47
106
 
48
- Net::SMTP.start(server, port, server, user, pass, auth) do |smtp|
49
- smtp.send_message msg, from, to
50
- end
107
+ Net::SMTP.start(server, port, server, user, pass, auth) do |smtp|
108
+ smtp.send_message msg, from, to
109
+ end
51
110
  end
52
111
 
53
112
  def self.counts(array)
@@ -55,9 +114,34 @@ Subject: #{subject}
55
114
  array.each do |e|
56
115
  counts[e] += 1
57
116
  end
117
+
118
+ class << counts; self;end.class_eval do
119
+ def to_s
120
+ sort{|a,b| a[1] == b[1] ? a[0] <=> b[0] : a[1] <=> b[1]}.collect{|k,c| "%3d\t%s" % [c, k]} * "\n"
121
+ end
122
+ end
123
+
58
124
  counts
59
125
  end
60
126
 
127
+ def self.proportions(array)
128
+ total = array.length
129
+
130
+ proportions = Hash.new 0
131
+
132
+ array.each do |e|
133
+ proportions[e] += 1.0 / total
134
+ end
135
+
136
+ class << proportions; self;end.class_eval do
137
+ def to_s
138
+ sort{|a,b| a[1] == b[1] ? a[0] <=> b[0] : a[1] <=> b[1]}.collect{|k,c| "%3d\t%s" % [c, k]} * "\n"
139
+ end
140
+ end
141
+
142
+ proportions
143
+ end
144
+
61
145
  IUPAC2BASE = {
62
146
  "A" => ["A"],
63
147
  "C" => ["C"],
@@ -85,6 +169,29 @@ Subject: #{subject}
85
169
  "U" => "A",
86
170
  }
87
171
 
172
+ THREE_TO_ONE_AA_CODE = {
173
+ "ala" => "A",
174
+ "arg" => "R",
175
+ "asn" => "N",
176
+ "asp" => "D",
177
+ "cys" => "C",
178
+ "glu" => "E",
179
+ "gln" => "Q",
180
+ "gly" => "G",
181
+ "his" => "H",
182
+ "ile" => "I",
183
+ "leu" => "L",
184
+ "lys" => "K",
185
+ "met" => "M",
186
+ "phe" => "F",
187
+ "pro" => "P",
188
+ "ser" => "S",
189
+ "thr" => "T",
190
+ "trp" => "W",
191
+ "tyr" => "Y",
192
+ "val" => "V"
193
+ }
194
+
88
195
  def self.IUPAC_to_base(iupac)
89
196
  IUPAC2BASE[iupac]
90
197
  end
@@ -259,7 +366,7 @@ Subject: #{subject}
259
366
 
260
367
  def self.lock(file, *args)
261
368
  FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exists? File.dirname(File.expand_path(file))
262
- lockfile = Lockfile.new(file + '.lock')
369
+ lockfile = Lockfile.new(file + '.lock', :max_age => 1200, :suspend => 240)
263
370
  lockfile.lock do
264
371
  yield file, *args
265
372
  end
@@ -344,24 +451,34 @@ Subject: #{subject}
344
451
  end
345
452
 
346
453
  def self.hash2md5(hash)
347
- o = {}
454
+ str = ""
348
455
  hash.keys.sort_by{|k| k.to_s}.each do |k|
349
456
  next if k == :monitor or k == "monitor" or k == :in_situ_persistence or k == "in_situ_persistence"
350
457
  v = hash[k]
351
458
  case
352
- when v.inspect =~ /:0x0/
353
- o[k] = v.inspect.sub(/:0x[a-f0-9]+@/,'')
354
- #when Resource::Path === v
355
- # o[k] = "" << String.new(v.to_s)
459
+ when Hash === v
460
+ str << k.to_s << "=>" << hash2md5(v)
461
+ when Symbol === v
462
+ str << k.to_s << "=>" << v.to_s
463
+ when String === v
464
+ str << k.to_s << "=>" << v
356
465
  else
357
- o[k] = v
466
+ v_ins = v.inspect
467
+
468
+ case
469
+ when v_ins =~ /:0x0/
470
+ str << k.to_s << "=>" << v_ins.sub(/:0x[a-f0-9]+@/,'')
471
+ else
472
+ str << k.to_s << "=>" << v.to_s
473
+ end
474
+
358
475
  end
359
476
  end
360
477
 
361
- if o.empty?
478
+ if str.empty?
362
479
  ""
363
480
  else
364
- Digest::MD5.hexdigest(o.sort_by{|k| k.to_s}.inspect)
481
+ Digest::MD5.hexdigest(str)
365
482
  end
366
483
  end
367
484
 
@@ -455,7 +572,7 @@ Subject: #{subject}
455
572
  raise FieldNotFoundError, "Field information missing" if fields.nil? && ! quiet
456
573
  fields.each_with_index{|f,i| return i if f == field}
457
574
  field_re = Regexp.new /#{field}/i
458
- fields.each_with_index{|f,i| return i if f =~ field_re}
575
+ fields.each_with_index{|f,i| return i if f =~ field_re}
459
576
  raise FieldNotFoundError, "Field #{ field.inspect } was not found" unless quiet
460
577
  end
461
578
 
@@ -477,134 +594,6 @@ Subject: #{subject}
477
594
 
478
595
  end
479
596
 
480
- module NamedArray
481
- extend ChainMethods
482
-
483
- self.chain_prefix = :named_array
484
- attr_accessor :fields
485
- attr_accessor :key
486
-
487
- def self.setup(array, fields, key = nil)
488
- array.extend NamedArray
489
- array.fields = fields
490
- array.key = key
491
- array
492
- end
493
-
494
- def merge(array)
495
- double = Array === array.first
496
- new = self.dup
497
- (0..length - 1).each do |i|
498
- if double
499
- new[i] = new[i] + array[i]
500
- else
501
- new[i] << array[i]
502
- end
503
- end
504
- new
505
- end
506
-
507
- def positions(fields)
508
- if Array == fields
509
- fields.collect{|field|
510
- Misc.field_position(@fields, field)
511
- }
512
- else
513
- Misc.field_position(@fields, fields)
514
- end
515
- end
516
-
517
- def named_array_get_brackets(key)
518
- if defined? Entity
519
- entity = (defined?(Entity) and Entity.respond_to?(:formats)) ? Entity.formats[key] : nil
520
- if entity
521
- elem = if entity.annotations.first == :format
522
- entity.setup(named_array_clean_get_brackets(Misc.field_position(fields, key)), key)
523
- else
524
- entity.setup(named_array_clean_get_brackets(Misc.field_position(fields, key)))
525
- end
526
- elem.context = self
527
- elem
528
- else
529
- named_array_clean_get_brackets(Misc.field_position(fields, key))
530
- end
531
- else
532
- named_array_clean_get_brackets(Misc.field_position(fields, key))
533
- end
534
- end
535
-
536
- def named_array_each(&block)
537
- if defined?(Entity) and not @fields.nil? and not @fields.empty?
538
- @fields.zip(self).each do |field,elem|
539
- entity = (defined?(Entity) and Entity.respond_to?(:formats)) ? Entity.formats[field] : nil
540
-
541
- if entity
542
- elem = elem.dup if elem.frozen?
543
- if entity.annotations.first == :format
544
- entity.setup(elem, field)
545
- else
546
- entity.setup(elem)
547
- end
548
- elem.context = self
549
- elem
550
- end
551
-
552
- yield(elem)
553
- elem
554
- end
555
- else
556
- named_array_clean_each &block
557
- end
558
- end
559
-
560
- def named_array_collect
561
- res = []
562
-
563
- named_array_each do |elem|
564
- if block_given?
565
- res << yield(elem)
566
- else
567
- res << elem
568
- end
569
- end
570
-
571
- res
572
- end
573
-
574
- def named_array_set_brackets(key,value)
575
- named_array_clean_set_brackets(Misc.field_position(fields, key), value)
576
- end
577
-
578
- def named_array_values_at(*keys)
579
- keys = keys.collect{|k| Misc.field_position(fields, k) }
580
- named_array_clean_values_at(*keys)
581
- end
582
-
583
- def zip_fields
584
- return [] if self.empty?
585
- zipped = Misc.zip_fields(self)
586
- zipped = zipped.collect{|v| NamedArray.setup(v, fields)}
587
- zipped
588
- end
589
-
590
- def detach(file)
591
- file_fields = file.fields.collect{|field| field.fullname}
592
- detached_fields = []
593
- self.fields.each_with_index{|field,i| detached_fields << i if file_fields.include? field.fullname}
594
- fields = self.fields.values_at *detached_fields
595
- values = self.values_at *detached_fields
596
- values = NamedArray.name(values, fields)
597
- values.zip_fields
598
- end
599
-
600
- def report
601
- fields.zip(self).collect do |field,value|
602
- "#{ field }: #{ Array === value ? value * "|" : value }"
603
- end * "\n"
604
- end
605
-
606
- end
607
-
608
597
  class RBBTError < StandardError
609
598
  attr_accessor :info
610
599
 
@@ -664,7 +653,7 @@ module IndiferentHash
664
653
 
665
654
  def self.setup(hash)
666
655
  return hash if IndiferentHash === hash
667
- hash.extend IndiferentHash
656
+ hash.extend IndiferentHash unless IndiferentHash === hash
668
657
  hash
669
658
  end
670
659
  end