xqsr3 0.32.3 → 0.37.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.
- checksums.yaml +4 -4
- data/lib/xqsr3/all_extensions.rb +6 -0
- data/lib/xqsr3/array_utilities.rb +10 -0
- data/lib/xqsr3/command_line_utilities.rb +10 -0
- data/lib/xqsr3/command_line_utilities/map_option_string.rb +3 -2
- data/lib/xqsr3/containers.rb +11 -0
- data/lib/xqsr3/containers/frequency_map.rb +18 -1
- data/lib/xqsr3/containers/multi_map.rb +290 -29
- data/lib/xqsr3/conversion.rb +11 -0
- data/lib/xqsr3/conversion/integer_parser.rb +3 -2
- data/lib/xqsr3/diagnostics.rb +11 -0
- data/lib/xqsr3/diagnostics/inspect_builder.rb +5 -1
- data/lib/xqsr3/extensions.rb +13 -0
- data/lib/xqsr3/extensions/array.rb +3 -0
- data/lib/xqsr3/extensions/hash.rb +6 -0
- data/lib/xqsr3/extensions/hash/except.rb +26 -0
- data/lib/xqsr3/extensions/hash/slice.rb +22 -0
- data/lib/xqsr3/extensions/io/writelines.rb +38 -6
- data/lib/xqsr3/extensions/test/unit/assert_raise_with_message.rb +22 -2
- data/lib/xqsr3/hash_utilities.rb +11 -0
- data/lib/xqsr3/hash_utilities/key_matching.rb +6 -4
- data/lib/xqsr3/internal_/test_unit_version_.rb +26 -0
- data/lib/xqsr3/io/writelines.rb +49 -13
- data/lib/xqsr3/quality.rb +8 -1
- data/lib/xqsr3/quality/parameter_checking.rb +3 -2
- data/lib/xqsr3/string_utilities.rb +16 -0
- data/lib/xqsr3/string_utilities/ends_with.rb +3 -2
- data/lib/xqsr3/string_utilities/nil_if_empty.rb +3 -2
- data/lib/xqsr3/string_utilities/nil_if_whitespace.rb +3 -2
- data/lib/xqsr3/string_utilities/quote_if.rb +7 -2
- data/lib/xqsr3/string_utilities/starts_with.rb +3 -2
- data/lib/xqsr3/string_utilities/to_symbol.rb +3 -2
- data/lib/xqsr3/string_utilities/truncate.rb +3 -2
- data/lib/xqsr3/version.rb +3 -2
- data/test/unit/containers/tc_multi_map.rb +174 -16
- data/test/unit/diagnostics/tc_exception_utilities.rb +7 -3
- data/test/unit/extensions/hash/tc_deep_transform.rb +0 -1
- data/test/unit/extensions/hash/tc_except.rb +67 -0
- data/test/unit/extensions/hash/tc_hash.rb +6 -0
- data/test/unit/extensions/hash/tc_slice.rb +31 -0
- data/test/unit/extensions/io/tc_writelines.rb +36 -0
- data/test/unit/extensions/kernel/tc_raise_with_options.rb +6 -3
- data/test/unit/tc_version.rb +1 -1
- metadata +22 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '048dfbb7beeff5b7e90df73f59be96e686611f91'
|
4
|
+
data.tar.gz: 815facf131a846b49eec30be5e45bf369383d52d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e77733d055c75114bcd38811e5af5f89726c563976d49b8d197246309ac6a2c92ade6cf66e812f81a02b17f682f530b870441fc9f8436b499179dee2165d539c
|
7
|
+
data.tar.gz: 38743b47b07c1b1876d680a759e6c9ec3e9aac7ef6482305a2dbe452fa5d1f28e0bb3b5921653778feb94b76a8f884f90eb03dbae7bad9dd6d5815fad9902308
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# ::Xqsr3::CommandLineUtilities::MapOptionString module
|
7
7
|
#
|
8
8
|
# Created: 15th April 2016
|
9
|
-
# Updated:
|
9
|
+
# Updated: 15th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
@@ -69,7 +69,8 @@ module MapOptionString
|
|
69
69
|
end
|
70
70
|
|
71
71
|
private
|
72
|
-
|
72
|
+
# @!visibility private
|
73
|
+
module MapOptionString_Helper_ # :nodoc: all
|
73
74
|
|
74
75
|
def self.map_option_string_with_options_ s, option_strings, options
|
75
76
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# Purpose: FrequencyMap container
|
6
6
|
#
|
7
7
|
# Created: 28th January 2005
|
8
|
-
# Updated:
|
8
|
+
# Updated: 15th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
@@ -77,6 +77,7 @@ class FrequencyMap
|
|
77
77
|
# fm[:z] # => 0
|
78
78
|
ByElement = Class.new do
|
79
79
|
|
80
|
+
# Create an instance of Xqsr3::FrequencyMap from an array
|
80
81
|
def self.[] *args
|
81
82
|
|
82
83
|
fm = FrequencyMap.new
|
@@ -180,12 +181,16 @@ class FrequencyMap
|
|
180
181
|
|
181
182
|
case rhs
|
182
183
|
when ::NilClass
|
184
|
+
|
183
185
|
return false
|
184
186
|
when ::Hash
|
187
|
+
|
185
188
|
return rhs.size == @elements.size && rhs == @elements
|
186
189
|
when self.class
|
190
|
+
|
187
191
|
return rhs.count == self.count && rhs == @elements
|
188
192
|
else
|
193
|
+
|
189
194
|
raise TypeError, "can compare #{self.class} only to instances of #{self.class} and #{::Hash}, but #{rhs.class} given"
|
190
195
|
end
|
191
196
|
|
@@ -407,6 +412,12 @@ class FrequencyMap
|
|
407
412
|
|
408
413
|
# Returns +true+ if an element with a count of the given +value+ is in the
|
409
414
|
# map; +false+ otherwise
|
415
|
+
#
|
416
|
+
# * *Parameters:*
|
417
|
+
# - +value+ (Integer) The value of the count for which to search
|
418
|
+
#
|
419
|
+
# * *Exceptions:*
|
420
|
+
# - +::TypeError+ if +value+ is not an Integer
|
410
421
|
def has_value? value
|
411
422
|
|
412
423
|
case value
|
@@ -437,6 +448,8 @@ class FrequencyMap
|
|
437
448
|
#
|
438
449
|
# @elements.keep_if
|
439
450
|
# end
|
451
|
+
=begin
|
452
|
+
=end
|
440
453
|
|
441
454
|
# Returns the element that has the given count, or +nil+ if none found
|
442
455
|
#
|
@@ -540,6 +553,8 @@ class FrequencyMap
|
|
540
553
|
self
|
541
554
|
end
|
542
555
|
|
556
|
+
# Removes a key-value pair from the instance and return as a two-item
|
557
|
+
# array
|
543
558
|
def shift
|
544
559
|
|
545
560
|
r = @elements.shift
|
@@ -589,11 +604,13 @@ class FrequencyMap
|
|
589
604
|
@elements.to_hash
|
590
605
|
end
|
591
606
|
|
607
|
+
# A string-form of the instance
|
592
608
|
def to_s
|
593
609
|
|
594
610
|
@elements.to_s
|
595
611
|
end
|
596
612
|
|
613
|
+
# An array of all frequencies (without element keys) in the instance
|
597
614
|
def values
|
598
615
|
|
599
616
|
@elements.values
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# Purpose: multimap container
|
6
6
|
#
|
7
7
|
# Created: 21st March 2007
|
8
|
-
# Updated:
|
8
|
+
# Updated: 15th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
@@ -73,16 +73,16 @@ class MultiMap < ::Hash
|
|
73
73
|
return self.new
|
74
74
|
when ::Hash
|
75
75
|
|
76
|
-
|
76
|
+
mm = self.new
|
77
77
|
|
78
78
|
arg.each do |k, v|
|
79
79
|
|
80
80
|
raise ArgumentError, "mapped elements in hashes must be arrays, #{v.class} given" unless v.kind_of? ::Array
|
81
81
|
|
82
|
-
|
82
|
+
mm.store k, *v
|
83
83
|
end
|
84
84
|
|
85
|
-
return
|
85
|
+
return mm
|
86
86
|
when ::Array
|
87
87
|
|
88
88
|
# accepted forms:
|
@@ -133,6 +133,8 @@ class MultiMap < ::Hash
|
|
133
133
|
# Initialises an instance
|
134
134
|
def initialize
|
135
135
|
|
136
|
+
@merge_is_multi = true
|
137
|
+
|
136
138
|
@inner = Hash.new
|
137
139
|
end
|
138
140
|
|
@@ -143,6 +145,16 @@ class MultiMap < ::Hash
|
|
143
145
|
return @inner[key]
|
144
146
|
end
|
145
147
|
|
148
|
+
# Adds/assigns a new key+values pair. Equivalent to
|
149
|
+
#
|
150
|
+
# store(key, *values)
|
151
|
+
#
|
152
|
+
# * *Parameters:*
|
153
|
+
# - +key+ The element key
|
154
|
+
# - +values+ (Array) The values to be associated with the key
|
155
|
+
#
|
156
|
+
# * *Exceptions:*
|
157
|
+
# - +::TypeError+ if +values+ is not an array
|
146
158
|
def []= key, values
|
147
159
|
|
148
160
|
values = [] if values.nil?
|
@@ -203,9 +215,17 @@ class MultiMap < ::Hash
|
|
203
215
|
@inner.delete key
|
204
216
|
end
|
205
217
|
|
218
|
+
# Calls _block_ once for each key-value pair, passing the key and each
|
219
|
+
# of its values in turn. If the values for a given key are empty and
|
220
|
+
# +defaults+ is not empty, the block is invoked for that key (with
|
221
|
+
# +defaults[0]+) once
|
222
|
+
#
|
223
|
+
# * *Exceptions:*
|
224
|
+
# - +ArgumentError+ if more than 1 +defaults+ is provided, or no block is given
|
206
225
|
def each *defaults
|
207
226
|
|
208
227
|
raise ArgumentError, "may only supply 0 or 1 defaults" if defaults.size > 1
|
228
|
+
raise ArgumentError, 'block is required' unless block_given?
|
209
229
|
|
210
230
|
@inner.each do |key, values|
|
211
231
|
|
@@ -220,8 +240,8 @@ class MultiMap < ::Hash
|
|
220
240
|
end
|
221
241
|
end
|
222
242
|
|
223
|
-
# Calls _block_ once for each
|
224
|
-
#
|
243
|
+
# Calls _block_ once for each key in the instance, passing the key. If no
|
244
|
+
# block is provided, an enumerator is returned
|
225
245
|
def each_key
|
226
246
|
|
227
247
|
return @inner.each_key unless block_given?
|
@@ -229,26 +249,46 @@ class MultiMap < ::Hash
|
|
229
249
|
@inner.each_key { |key| yield key }
|
230
250
|
end
|
231
251
|
|
252
|
+
# Calls _block_ once for each key-values pair, passing the key and its
|
253
|
+
# values array. If no block is provided, an enumerator is returned
|
232
254
|
def each_unflattened
|
233
255
|
|
256
|
+
return @inner.each unless block_given?
|
257
|
+
|
234
258
|
@inner.each { |key, value| yield key, value }
|
235
259
|
end
|
236
260
|
|
261
|
+
# Calls _block_ once for each key-values pair, passing the key and its
|
262
|
+
# values array and a key index. If no block is provided, an enumerator
|
263
|
+
# is returned
|
237
264
|
def each_unflattened_with_index
|
238
265
|
|
266
|
+
return @inner.each_with_index unless block_given?
|
267
|
+
|
239
268
|
@inner.each_with_index { |kv, index| yield kv, index }
|
240
269
|
end
|
241
270
|
|
271
|
+
# Calls _block_ once for each value in the instance, passing the value.
|
272
|
+
# If no block is provided, an enumerator is returned
|
242
273
|
def each_value
|
243
274
|
|
275
|
+
return @inner.each_value unless block_given?
|
276
|
+
|
244
277
|
@inner.each do |key, values|
|
245
278
|
|
246
279
|
values.each { |value| yield value }
|
247
280
|
end
|
248
281
|
end
|
249
282
|
|
283
|
+
# Calls _block_ once for each key-values, passing the key and each of its
|
284
|
+
# values and a value index
|
285
|
+
#
|
286
|
+
# * *Exceptions:*
|
287
|
+
# - +ArgumentError+ if no block is given
|
250
288
|
def each_with_index
|
251
289
|
|
290
|
+
raise ArgumentError, 'block is required' unless block_given?
|
291
|
+
|
252
292
|
index = 0
|
253
293
|
self.each do |key, value|
|
254
294
|
|
@@ -276,18 +316,26 @@ class MultiMap < ::Hash
|
|
276
316
|
end
|
277
317
|
end
|
278
318
|
|
279
|
-
|
319
|
+
# Returns the values associated with the given key
|
320
|
+
#
|
321
|
+
# * *Parameters:*
|
322
|
+
# - +key+ The key
|
323
|
+
# - +default+ The default value
|
324
|
+
def fetch key, default = (default_parameter_defaulted_ = true; nil), &block
|
280
325
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
326
|
+
unless default_parameter_defaulted_
|
327
|
+
|
328
|
+
case default
|
329
|
+
when ::NilClass, ::Array
|
330
|
+
;
|
331
|
+
else
|
332
|
+
raise TypeError, "default parameter ('#{default}') must be of type #{::Array}, but was of type #{default.class}"
|
333
|
+
end
|
286
334
|
end
|
287
335
|
|
288
336
|
unless @inner.has_key? key
|
289
337
|
|
290
|
-
return default unless
|
338
|
+
return default unless default_parameter_defaulted_
|
291
339
|
|
292
340
|
if block_given?
|
293
341
|
|
@@ -349,31 +397,127 @@ class MultiMap < ::Hash
|
|
349
397
|
@inner.has_key? key
|
350
398
|
end
|
351
399
|
|
400
|
+
# Returns +true+ if any key has the given +value+; +false+ otherwise
|
401
|
+
#
|
402
|
+
# * *Parameters:*
|
403
|
+
# - +value+ The value for which to search
|
352
404
|
def has_value? value
|
353
405
|
|
354
|
-
@inner.
|
406
|
+
@inner.each do |k, vals|
|
407
|
+
|
408
|
+
return true if vals.include? value
|
409
|
+
end
|
410
|
+
|
411
|
+
false
|
412
|
+
end
|
413
|
+
|
414
|
+
# Returns +true+ if any key has the given +values+; +false+ otherwise
|
415
|
+
#
|
416
|
+
# * *Parameters:*
|
417
|
+
# - +values+ (Array) The values for which to search
|
418
|
+
#
|
419
|
+
# * *Exceptions:*
|
420
|
+
# - +::TypeError+ if +value+ is not an Array
|
421
|
+
def has_values? values
|
422
|
+
|
423
|
+
raise TypeError, "'values' parameter must be of type #{::Array}" unless Array === values
|
424
|
+
|
425
|
+
@inner.has_value? values
|
355
426
|
end
|
356
427
|
|
357
|
-
|
428
|
+
# Returns the key for the given value(s)
|
429
|
+
#
|
430
|
+
# * *Parameters:*
|
431
|
+
# - +values+ (Array) The value(s) for which to search
|
432
|
+
#
|
433
|
+
# If a single value is specified, the entries in the instance are
|
434
|
+
# searched first for an exact match to all (1) value(s); if that fails,
|
435
|
+
# then the first key with a values containing the given value is
|
436
|
+
# returned
|
437
|
+
def key *values
|
438
|
+
|
439
|
+
case values.size
|
440
|
+
when 0
|
441
|
+
|
442
|
+
return nil
|
443
|
+
when 1
|
444
|
+
|
445
|
+
i = nil
|
446
|
+
|
447
|
+
@inner.each do |k, vals|
|
448
|
+
|
449
|
+
return k if vals == values
|
450
|
+
|
451
|
+
if i.nil?
|
452
|
+
|
453
|
+
i = k if vals.include? values[0]
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
return i
|
458
|
+
else
|
459
|
+
|
460
|
+
@inner.each do |key, vals|
|
461
|
+
|
462
|
+
return key if vals == values
|
463
|
+
end
|
358
464
|
|
359
|
-
|
465
|
+
return nil
|
466
|
+
end
|
360
467
|
end
|
361
468
|
|
362
|
-
|
469
|
+
# The number of elements in the map
|
470
|
+
def length
|
363
471
|
|
364
|
-
|
472
|
+
@inner.size
|
473
|
+
end
|
365
474
|
|
366
|
-
|
475
|
+
# Returns a new instance containing a merging of the current instance and
|
476
|
+
# the +other+ instance
|
477
|
+
#
|
478
|
+
# NOTE: where any key is found in both merging instances the values
|
479
|
+
# resulting will be a concatenation of the sets of values
|
480
|
+
#
|
481
|
+
# * *Parameters:*
|
482
|
+
# - +other+ (MultiMap, Hash) The instance from which to merge
|
483
|
+
#
|
484
|
+
# * *Exceptions:*
|
485
|
+
# - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
|
486
|
+
def multi_merge other
|
367
487
|
|
368
|
-
|
369
|
-
fm_new.merge! fm
|
488
|
+
mm = self.class.new
|
370
489
|
|
371
|
-
|
490
|
+
mm.merge! self
|
491
|
+
mm.merge! other
|
492
|
+
|
493
|
+
mm
|
372
494
|
end
|
373
495
|
|
374
|
-
|
496
|
+
# Merges the contents of +other+ into the current instance
|
497
|
+
#
|
498
|
+
# NOTE: where any key is found in both merging instances the values
|
499
|
+
# resulting will be a concatenation of the sets of values
|
500
|
+
#
|
501
|
+
# * *Parameters:*
|
502
|
+
# - +other+ (MultiMap, Hash) The instance from which to merge
|
503
|
+
#
|
504
|
+
# * *Exceptions:*
|
505
|
+
# - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
|
506
|
+
def multi_merge! other
|
507
|
+
|
508
|
+
case other
|
509
|
+
when self.class
|
510
|
+
|
511
|
+
;
|
512
|
+
when ::Hash
|
375
513
|
|
376
|
-
|
514
|
+
;
|
515
|
+
else
|
516
|
+
|
517
|
+
raise TypeError, "parameter must be an instance of #{self.class} or #{Hash}"
|
518
|
+
end
|
519
|
+
|
520
|
+
other.each do |k, v|
|
377
521
|
|
378
522
|
self.push k, v
|
379
523
|
end
|
@@ -381,6 +525,96 @@ class MultiMap < ::Hash
|
|
381
525
|
self
|
382
526
|
end
|
383
527
|
|
528
|
+
# Returns a new instance containing a merging of the current instance and
|
529
|
+
# the +other+ instance
|
530
|
+
#
|
531
|
+
# NOTE: where any key is found in both merging instances the values from
|
532
|
+
# +other+ will be used
|
533
|
+
#
|
534
|
+
# * *Parameters:*
|
535
|
+
# - +other+ (MultiMap, Hash) The instance from which to merge
|
536
|
+
#
|
537
|
+
# * *Exceptions:*
|
538
|
+
# - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
|
539
|
+
def strict_merge other
|
540
|
+
|
541
|
+
mm = self.class.new
|
542
|
+
|
543
|
+
mm.strict_merge! self
|
544
|
+
mm.strict_merge! other
|
545
|
+
|
546
|
+
mm
|
547
|
+
end
|
548
|
+
|
549
|
+
# Merges the contents of +other+ into the current instance
|
550
|
+
#
|
551
|
+
# NOTE: where any key is found in both merging instances the values from
|
552
|
+
# +other+ will be used
|
553
|
+
#
|
554
|
+
# * *Parameters:*
|
555
|
+
# - +other+ (MultiMap, Hash) The instance from which to merge
|
556
|
+
#
|
557
|
+
# * *Exceptions:*
|
558
|
+
# - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
|
559
|
+
def strict_merge! other
|
560
|
+
|
561
|
+
case other
|
562
|
+
when self.class
|
563
|
+
|
564
|
+
other.each_unflattened do |k, vals|
|
565
|
+
|
566
|
+
self.store k, *vals
|
567
|
+
end
|
568
|
+
when ::Hash
|
569
|
+
|
570
|
+
other.each do |k, v|
|
571
|
+
|
572
|
+
self.store k, v
|
573
|
+
end
|
574
|
+
else
|
575
|
+
|
576
|
+
raise TypeError, "parameter must be an instance of #{self.class} or #{Hash}"
|
577
|
+
end
|
578
|
+
|
579
|
+
self
|
580
|
+
end
|
581
|
+
|
582
|
+
# See #merge
|
583
|
+
def merge other
|
584
|
+
|
585
|
+
if @merge_is_multi
|
586
|
+
|
587
|
+
multi_merge other
|
588
|
+
else
|
589
|
+
|
590
|
+
strict_merge other
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
# See #merge!
|
595
|
+
def merge! other
|
596
|
+
|
597
|
+
if @merge_is_multi
|
598
|
+
|
599
|
+
multi_merge! other
|
600
|
+
else
|
601
|
+
|
602
|
+
strict_merge! other
|
603
|
+
end
|
604
|
+
end
|
605
|
+
|
606
|
+
# Pushes the given +key+ and +values+. If the +key+ is already in the
|
607
|
+
# map then the +values+ will be concatenated with those already present
|
608
|
+
#
|
609
|
+
# === Signature
|
610
|
+
#
|
611
|
+
# * *Parameters:*
|
612
|
+
# - +key+ The element key
|
613
|
+
# - +values+ (*Array) The value(s) to be pushed
|
614
|
+
#
|
615
|
+
# === Exceptions
|
616
|
+
# - +::RangeError+ raised if the value of +count+ results in a negative count for the given element
|
617
|
+
# - +::TypeError+ if +count+ is not an +::Integer+
|
384
618
|
def push key, *values
|
385
619
|
|
386
620
|
@inner[key] = [] unless @inner.has_key? key
|
@@ -388,33 +622,60 @@ class MultiMap < ::Hash
|
|
388
622
|
@inner[key].push(*values)
|
389
623
|
end
|
390
624
|
|
625
|
+
# Removes a key-value pair from the instance and return as a two-item
|
626
|
+
# array
|
391
627
|
def shift
|
392
628
|
|
393
629
|
@inner.shift
|
394
630
|
end
|
395
631
|
|
396
|
-
|
397
|
-
|
398
|
-
@inner.size
|
399
|
-
end
|
632
|
+
alias size length
|
400
633
|
|
634
|
+
# Causes an element with the given +key+ and +values+ to be stored. If an
|
635
|
+
# element with the given +key+ already exists, its values will b
|
636
|
+
# replaced
|
401
637
|
def store key, *values
|
402
638
|
|
403
639
|
@inner[key] = values
|
404
640
|
end
|
405
641
|
|
642
|
+
# Converts instance to an array of +[key,value]+ pairs
|
406
643
|
def to_a
|
407
644
|
|
408
645
|
self.flatten
|
409
646
|
end
|
410
647
|
|
648
|
+
# Obtains reference to internal hash instance (which must *not* be modified)
|
411
649
|
def to_h
|
412
650
|
|
413
|
-
@inner.
|
651
|
+
@inner.to_h
|
414
652
|
end
|
415
653
|
|
654
|
+
# Obtains equivalent hash to instance
|
655
|
+
def to_hash
|
656
|
+
|
657
|
+
@elements.to_hash
|
658
|
+
end
|
659
|
+
|
660
|
+
# A string-form of the instance
|
661
|
+
def to_s
|
662
|
+
|
663
|
+
@inner.to_s
|
664
|
+
end
|
665
|
+
|
666
|
+
# An array of all values in the instance
|
416
667
|
def values
|
417
668
|
|
669
|
+
r = []
|
670
|
+
|
671
|
+
@inner.values.each { |vals| r += vals }
|
672
|
+
|
673
|
+
r
|
674
|
+
end
|
675
|
+
|
676
|
+
# An array of all sets of values in the instance
|
677
|
+
def values_unflattened
|
678
|
+
|
418
679
|
@inner.values
|
419
680
|
end
|
420
681
|
end # class MultiMap
|