libis-workflow-mongoid 2.0.5 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,867 +0,0 @@
1
- module MapWithIndifferentAccess
2
-
3
- class List
4
- extend Forwardable
5
- include MapWithIndifferentAccess::WrapsCollection
6
-
7
- def first
8
- self.at(0)
9
- end
10
-
11
- def last
12
- self.at(-1)
13
- end
14
-
15
- # Try to convert `from_obj` into a {List}.
16
- #
17
- # @return [List]
18
- # converted object if `from_obj` is convertible.
19
- #
20
- # @return [nil]
21
- # if `from_obj` cannot be converted for any reason.
22
- def self.try_convert(from_obj)
23
- if self === from_obj
24
- from_obj
25
- else
26
- array = ::Array.try_convert( from_obj )
27
- new( array ) if array
28
- end
29
- end
30
-
31
- # Try to convert `obj`, which might be a {List} into an
32
- # `Array`.
33
- #
34
- # @return [Array]
35
- # converted object if `obj` is convertible.
36
- #
37
- # @return [nil]
38
- # if `obj` cannot be converted for any reason.
39
- def self.try_deconstruct(obj)
40
- if self === obj
41
- obj.inner_array
42
- elsif obj.respond_to?(:to_ary )
43
- a = obj.to_ary
44
- ::Array === a ? a : nil
45
- else
46
- nil
47
- end
48
- end
49
-
50
- # @!attribute inner_array
51
- # @return [Array]
52
- #
53
- # Alias for {#inner_collection}. The encapsulated `Array`
54
- # instance.
55
- alias inner_array inner_collection
56
-
57
- # @!method to_a
58
- #
59
- # Alias for {#inner_collection}. Returns the
60
- # encapsulated `Array` instance.
61
-
62
- # Use class_eval to hide the aliasing from Yard doc.
63
- class_eval 'alias to_a inner_collection', __FILE__, __LINE__
64
-
65
- # Initializes a new instance of {List} that encapsulates a
66
- # new empty `Array` or the `Array` coerced from the given
67
- # `basis`.
68
- #
69
- # When a {List} is given as a `basis`, this results on the
70
- # given and new instances sharing the same {#inner_array}.
71
- # There is no obvious reason to do that on purpose, but there
72
- # is also no particular harm in allowing it to happen.
73
- #
74
- # @param [Array, List, Object] basis
75
- # An `Array` or an object that can be implicitly coerced to
76
- # an `Array`
77
- def initialize(basis = [])
78
- use_basis = basis
79
- use_basis = basis.inner_array if self.class === basis
80
- use_basis = ::Array.try_convert( use_basis )
81
- raise ArgumentError, "Could not convert #{basis.inspect} into an ::Array" unless use_basis
82
- @inner_collection = use_basis
83
- end
84
-
85
- # Element Assignment — Sets the element at index, or replaces
86
- # a subarray from the start index for length elements, or
87
- # replaces a subarray specified by the range of indices.
88
- #
89
- # The given object or array is internalized befor being
90
- # ussed for assignment into the {#inner_array}.
91
- #
92
- # @return the given value or array.
93
- #
94
- # @see Values.internalize
95
- # @see #push
96
- # @see #unshift
97
- #
98
- # @overload []=(index, value)
99
- # @param index [Fixnum]
100
- # @param value [Object]
101
- #
102
- # @overload []=(start, length, array_or_value)
103
- # @param start [Fixnum]
104
- # @param length [Fixnum]
105
- # @param array_or_value [Array, List Object, nil]
106
- #
107
- # @overload []=(range, array_or_value)
108
- # @param range [Ramge]
109
- # @param array_or_value [Array, List, Object, nil]
110
- def []=(index, length_or_value, *maybe_value)
111
- arg_count = 2 + maybe_value.length
112
- unless (2..3) === arg_count
113
- raise ArgumentError, "wrong number of arguments (#{arg_count} for 2..3)"
114
- end
115
-
116
- if maybe_value.empty?
117
- maybe_length = []
118
- value_or_values = length_or_value
119
- else
120
- maybe_length = [length_or_value]
121
- value_or_values = maybe_value.first
122
- end
123
-
124
- if (
125
- ( !maybe_length.empty? || Range === index ) &&
126
- ( value_array = List.try_deconstruct( value_or_values ) )
127
- )
128
- value_array = value_array.map{ |v| Values << v }
129
- inner_array[ index, *maybe_length ] = value_array
130
- else
131
- value = Values << value_or_values
132
- inner_array[ index, *maybe_length ] = value
133
- end
134
- end
135
-
136
- # @!method []
137
- # Returns the element at index, or returns a subarray
138
- # starting at the start index and continuing for length
139
- # elements, or returns a subarray specified by range of
140
- # indices.
141
- #
142
- # Externalizes the result before returning it.
143
- #
144
- # @see Values.externalize
145
- #
146
- # @overload [](index)
147
- # @param index [Fixnum]
148
- # @return [Object]
149
- #
150
- # @overload [](start, length)
151
- # @param start [Fixnum]
152
- # @param length [Fixnum]
153
- # @return [List]
154
- #
155
- # @overload [](range)
156
- # @param range [Range]
157
- # @return [List]
158
- #
159
- # @overload slice(index)
160
- # @param index [Fixnum]
161
- # @return [Object]
162
- #
163
- # @overload slice(start, length)
164
- # @param start [Fixnum]
165
- # @param length [Fixnum]
166
- # @return [List]
167
- #
168
- # @overload slice(range)
169
- # @param range [Range]
170
- # @return [List]
171
-
172
- ['[]', 'slice'].each do |method_name|
173
- class_eval <<-EOS, __FILE__, __LINE__ + 1
174
-
175
- def #{method_name}(index, *maybe_length)
176
- arg_count = 1 + maybe_length.length
177
- unless (1..2) === arg_count
178
- raise ArgumentError, "wrong number of arguments (\#{arg_count} for 1..2)"
179
- end
180
-
181
- if !maybe_length.empty? || Range === index
182
- value_array = inner_array.#{method_name}( index, *maybe_length )
183
- value_array.map!{ |v| Values >> v }
184
- List.new( value_array )
185
- else
186
- value = inner_array.#{method_name}( index )
187
- Values >> value
188
- end
189
- end
190
-
191
- EOS
192
- end
193
-
194
- # Returns the externalization of the element at `index`. A
195
- # negative index counts from the end of the list. Returns
196
- # `nil` if the index is out of range.
197
- #
198
- # @see #[]
199
- def at(index)
200
- item = inner_array.at( index )
201
- Values >> item
202
- end
203
-
204
- # Append. Pushes the given object on to the end of the list.
205
- # Returns the array itself, so several appends may be chained
206
- # together.
207
- #
208
- # Internalizes the given onject before appending it to the
209
- # target's {#inner_array}.
210
- #
211
- # @return [List]
212
- # @see #push
213
- def <<(value)
214
- value = Values << value
215
- inner_array << value
216
- self
217
- end
218
-
219
- # Append. Pushes the given object(s) on to the end of the
220
- # list. Returns the array itself, so several appends may be
221
- # chained together.
222
- #
223
- # Internalizes each given object before appending it to the
224
- # target's {#inner_array}.
225
- #
226
- # @return [List]
227
- # @see #<<
228
- # @see #pop
229
- # @see Values.internalize
230
- def push(*values)
231
- values.map!{ |v| Values << v }
232
- inner_array.push *values
233
- self
234
- end
235
-
236
- # Prepends objects to the front of the list, moving other
237
- # elements upwards.
238
- #
239
- # Internalizes each value before prepending it to the
240
- # target's {#inner_array}.
241
- #
242
- # See also {#shift} for the opposite effect.
243
- #
244
- # @return [List]
245
- # @see #shift
246
- # @see Values.internalize
247
- def unshift(*values)
248
- values.map!{ |v| Values << v }
249
- inner_array.unshift *values
250
- self
251
- end
252
-
253
- # Inserts the given values before the element with the given
254
- # index.
255
- #
256
- # Internalizes the values before inserting them into the
257
- # target's {#inner_array}.
258
- #
259
- # Negative indices count backwards from the end of the array,
260
- # where -1 is the last element. If a negative index is used,
261
- # the given values will be inserted after that element, so
262
- # using an index of -1 will insert the values at the end of
263
- # the list.
264
- #
265
- # @return [List]
266
- # @see Values.internalize
267
- def insert(index, *values)
268
- values.map!{ |v| Values << v }
269
- inner_array.insert(index, *values)
270
- self
271
- end
272
-
273
- # Appends elements of `other` (a `List` or other
274
- # `Array`-like object) to the target `List`.
275
- #
276
- # @param other [List, Array, Object]
277
- # @return [List] The target list.
278
- #
279
- # @see #+
280
- def concat(other)
281
- other = self.class.try_deconstruct(other) || other
282
- inner_array.concat other
283
- self
284
- end
285
-
286
- # Returns a {List} containing the elements in self
287
- # corresponding to the given selector(s).
288
- #
289
- # The selectors may be either `Integer` indices or
290
- # `Range`s.
291
- #
292
- # @return List
293
- def values_at(*indexes)
294
- inner_result = inner_array.values_at( *indexes )
295
- Values >> inner_result
296
- end
297
-
298
- # Tries to retrieve the element at position `index`, but
299
- # raises an `IndexError` exception or uses a default value
300
- # when an invalid index is referenced.
301
- #
302
- # Returns the externalization of the retrieved value.
303
- #
304
- # @see MapWithIndifferentAccess::Values.externalize
305
- #
306
- # @overload fetch(index)
307
- # Tries to retrieve the element at position `index`, but
308
- # raises an `IndexError` exception if the referenced index
309
- # lies outside of the array bounds.
310
- #
311
- # @raise [IndexError]
312
- #
313
- # @overload fetch(index, default)
314
- # Tries to retrieve the element at position `index`, but
315
- # uses the given default if the referenced index lies
316
- # outside of the array bounds.
317
- #
318
- # @overload fetch(index)
319
- # @yieldparam index
320
- # Tries to retrieve the element at position `index`, but if
321
- # the referenced index lies outside of the array bounds,
322
- # calls the given block, and uses the block call result.
323
- def fetch(index, *args)
324
- item =
325
- if block_given?
326
- inner_array.fetch( index, *args ){ |idx| yield idx }
327
- else
328
- inner_array.fetch( index, *args )
329
- end
330
- Values >> item
331
- end
332
-
333
- # @!method shift(*maybe_n)
334
- # Removes and returns the first element or first `n`
335
- # elements of the array, shifting all of the other elements
336
- # downward.
337
- #
338
- # Returns the externalization of the removed element or
339
- # array of elements
340
- #
341
- # See {#unshift} for the opposite effect.
342
- #
343
- # @see #unshift
344
- # @see #pop
345
- #
346
- # @overload shift()
347
- # Removes the first element and returns it, shifting all
348
- # other elements down by one. Returns nil if the array is
349
- # empty.
350
- #
351
- # @return [Object, nil]
352
- #
353
- # @overload shift(n)
354
- # Returns a {List} of the first `n` elements (or less) just
355
- # like `array.slice!(0, n)` does, but also removing those
356
- # elements from the target.
357
- #
358
- # @return [List]
359
-
360
- # @!method pop(*maybe_n)
361
- # Removes and returns the last element or last `n` elements
362
- # of the array.
363
- #
364
- # Returns the externalization of the removed element or array
365
- # of elements
366
- #
367
- # See {#push} for the opposite effect.
368
- #
369
- # @see #push
370
- # @see #shift
371
- #
372
- # @overload pop()
373
- # Removes the last element and returns it. Returns nil if
374
- # the array is empty.
375
- #
376
- # @return [Object, nil]
377
- #
378
- # @overload pop(n)
379
- # Returns a {MapWithIndifferentAccess::List} of the last
380
- # `n` elements (or less) just like `array.slice!(-n, n)`
381
- # does, but also removing those elements from the target.
382
- #
383
- # @param n [Fixnum]
384
- # @return [MapWithIndifferentAccess::List]
385
- #
386
-
387
- %w(shift pop).each do |method_name|
388
- class_eval <<-EOS, __FILE__, __LINE__ + 1
389
-
390
- def #{method_name}(*maybe_n)
391
- arg_count = maybe_n.length
392
- unless (0..1) === arg_count
393
- raise ArgumentError, "wrong number of arguments (\#{arg_count} for 0..1)"
394
- end
395
- if maybe_n.empty?
396
- Values >> inner_array.#{method_name}
397
- else
398
- inner_result = inner_array.#{method_name}( *maybe_n )
399
- List.new( inner_result )
400
- end
401
- end
402
-
403
- EOS
404
- end
405
-
406
- # Deletes the element at the specified `index`, returning the
407
- # externalization of that element, or `nil` if the index is
408
- # out of range.
409
- #
410
- # @param index [Fixnum]
411
- # @return [Object, nil]
412
- #
413
- # @see #slice
414
- # @see Values.externalize
415
- def delete_at(index)
416
- inner_result = inner_array.delete_at( index )
417
- Values >> inner_result
418
- end
419
-
420
- # @!method &(other)
421
- # @param other [List, Array, Object]
422
- # @return [List]
423
- #
424
- # Set Intersection. Returns a new {List} containing
425
- # elements common to the target {List} and `other` (a
426
- # `List` or other `Array`-like object), excluding any
427
- # duplicate items. The order is preserved from the
428
- # original list.
429
- #
430
- # It compares elements using their `#hash` and `#eql?`
431
- # methods for efficiency.
432
- #
433
- # Note that this does not recongnize items of `Map` type as
434
- # equal just because they are equal by `#==`, which can be
435
- # the case when they have equivalent keys that differ by
436
- # `String`/`Symbol` type. You might therefore wish to call
437
- # {#&} for lists that have first had their keys
438
- # deeply-stringified or deeply-symbolized.
439
-
440
- # @!method |(other)
441
- # @param other [List, Array, Object]
442
- # @return [List]
443
- #
444
- # Set Union. Returns a new {List} by joining the target
445
- # `List` with `other` (a `List` or other `Array`-like
446
- # object), excluding any duplicates and preserving the
447
- # order from the original `List`.
448
- #
449
- # It compares elements using their `#hash` and `#eql?`
450
- # methods for efficiency.
451
- #
452
- # Note that this does not recongnize items of `Map` type as
453
- # equal just because they are equal by `#==`, which can be
454
- # the case when they have equivalent keys that differ by
455
- # `String`/`Symbol` type. You might therefore wish to call
456
- # {#|} for lists that have first had their keys
457
- # deeply-stringified or deeply-symbolized.
458
-
459
- # @!method +(other)
460
- # @param other [List, Array, Object]
461
- # @return [List]
462
- #
463
- # Concatenation. Returns a new {List} built by
464
- # concatenating `other` (a `List` or other `Array`-like
465
- # object) to the target `List`.
466
- #
467
- # @see #concat
468
-
469
- # @!method -(other)
470
- # @param other [List, Array, Object]
471
- # @return [List]
472
- #
473
- # Difference. Returns a new {List} that is a copy of the
474
- # original, removing any items that also appear in
475
- # `other` (a `List` or other `Array`-like object). The
476
- # order is preserved from the original `List`.
477
- #
478
- # It compares elements using their `#hash` and `#eql?`
479
- # methods for efficiency.
480
- #
481
- # Note that this does not recongnize items of `Map` type as
482
- # equal just because they are equal by `#==`, which can be
483
- # the case when they have equivalent keys that differ by
484
- # `String`/`Symbol` type. You might therefore wish to call
485
- # {#-} for lists that have first had their keys
486
- # deeply-stringified or deeply-symbolized.
487
-
488
- %w( & | + - ).each do |method_name|
489
- class_eval <<-EOS, __FILE__, __LINE__ + 1
490
-
491
- def #{method_name}(other)
492
- other = self.class.try_deconstruct( other ) || other
493
- inner_result = inner_array.#{method_name}(other)
494
- List.new( inner_result )
495
- end
496
-
497
- EOS
498
- end
499
-
500
- # @!method join(separator=$,)
501
- # @param separator [String]
502
- # @return [String]
503
- #
504
- # Returns a string consisting of `String`-converted item
505
- # values from the target `List` separated by the
506
- # `separator` string. If no `separator` or `nil` is given,
507
- # uses the value of `$,` as the separator. Treats a `nil`
508
- # `$,` value as a blank string.
509
- #
510
- # The items are not externalized before being converted to
511
- # `String`s, so `my_map.join` is exactly equivalent to
512
- # `my_map.inner_array.join`.
513
- #
514
- # @see Array#join
515
- def_delegator :inner_array, :join
516
-
517
- # Repetition.
518
- #
519
- # @overload *(n_copies)
520
- # @return [Map]
521
- #
522
- # Returns a new `List` built by concatenating `n_copies`
523
- # copies of itself together.
524
- #
525
- # @overload *(separator)
526
- # @return [String]
527
- #
528
- # Equivalent to `target_list.join(separator)`.
529
- def *(n_copies_or_separator)
530
- result = inner_array * n_copies_or_separator
531
- result = List.new( result ) if Array === result
532
- result
533
- end
534
-
535
- # Deletes all items from self, the externalizations of which
536
- # are equal to the externalization of `obj`.
537
- #
538
- # Returns the externalization of the last deleted item if
539
- # applicable.
540
- #
541
- # @see Values.externalize
542
- #
543
- # @overload delete(obj)
544
- # Returns `nil` if no matching items are found.
545
- #
546
- # @overload delete(obj)
547
- # @yield
548
- # Returns the externalization of the block result is no
549
- # matching items are found.
550
- def delete(obj)
551
- obj = Values >> obj
552
- removed_items = false
553
- result = nil
554
- inner_array.delete_if{ |v|
555
- v = Values >> v
556
- if v == obj
557
- result = v
558
- removed_items = true
559
- true
560
- end
561
- }
562
- if !removed_items && block_given?
563
- result = Values >> yield( obj )
564
- end
565
- result
566
- end
567
-
568
- # Returns a new instance with duplicate items omitted.
569
- # Items are considered equal if their `#hash` values are
570
- # equal and comparison using `#eql?` returns `true`.
571
- #
572
- # If a block is given, then externalized items are passed to
573
- # the block, and the return values from the block will be
574
- # used for dupliacte-check comparison.
575
- #
576
- # Note that items externally represented as `Map`s that are
577
- # equal according to {Map#==} will not necessarily be
578
- # identified as duplicates since they can still differ
579
- # according to {Map#eql} if their encapsulated `Hash`
580
- # objects are unequal due to key `String`/`Symbol` type
581
- # differences. You might therefore want to ensure that the
582
- # target `List` has been deeply stringified or symbolized
583
- # before calling {#uniq!} on it.
584
- #
585
- # @return [List]
586
- #
587
- # @see #uniq!
588
- def uniq
589
- result = dup
590
- if block_given?
591
- result.uniq!{ |item| yield( item ) }
592
- else
593
- result.uniq!
594
- end
595
- result
596
- end
597
-
598
- # Deletes duplicate items from the target's {#inner_array},
599
- # leaving only unique items remaining. Items are considered
600
- # equal if their `#hash` values are equal and comparison
601
- # using `#eql?` returns `true`.
602
- #
603
- # Returns the target `List` if any duplicates were found and
604
- # removed. Otherwise, returns `nil`.
605
- #
606
- # If a block is given, then externalized items are passed to
607
- # the block, and the return values from the block will be
608
- # used for dupliacte-check comparison.
609
- #
610
- # Note that items externally represented as `Map`s that are
611
- # equal according to {Map#==} will not necessarily be
612
- # identified as duplicates since they can still differ
613
- # according to {Map#eql} if their encapsulated `Hash`
614
- # objects are unequal due to key `String`/`Symbol` type
615
- # differences. You might therefore want to ensure that the
616
- # target `List` has been deeply stringified or symbolized
617
- # before calling {#uniq} on it.
618
- #
619
- # @return [List, nil]
620
- #
621
- # @see #uniq
622
- def uniq!
623
- inner_result =
624
- if block_given?
625
- inner_array.uniq!{ |item|
626
- yield( Values >> item )
627
- }
628
- else
629
- inner_array.uniq!
630
- end
631
-
632
- inner_result && self
633
- end
634
-
635
- # Equality. The target is equal to the given `Array`-like
636
- # object if both contain the same number of elements, and
637
- # externalizations of corresponding items in itself and the
638
- # given object are equal according to `#==`.
639
- #
640
- # @return [Boolean]
641
- #
642
- # @see Values.externalize
643
- def ==(other)
644
- same_class = self.class === other
645
-
646
- return false unless same_class || other.respond_to?(:to_ary )
647
-
648
- # Optimizations
649
- return true if equal?( other )
650
- return true if same_class && inner_array == other.inner_array
651
-
652
- return false unless length == other.length
653
- zip( other ).all? { |(v,other_v)| v == Values >> other_v }
654
- end
655
-
656
- # @param [List, Array, Object]
657
- # @return [1, 0, -1, nil]
658
- #
659
- # Comparison. Returns an integer (-1, 0, or +1) if this
660
- # `List` is less than, equal to, or greater than `other`, and
661
- # `other` is a `List` or other `Array`-like object that can
662
- # be coerced to a `List`.
663
- #
664
- # Each externaized item in the target `List` is compared to
665
- # the corresponding externalized item in `other` (using the
666
- # `<=>` operator). As soon as a comparison is non zero (i.e.
667
- # the two corresponding elements are not equal), that result
668
- # is returned for the whole array comparison.
669
- #
670
- # If all the elements are equal, then the result is based on
671
- # a comparison of the list lengths. Thus, two `List`s are
672
- # "equal" according to {#<=>} if, and only if, they have the
673
- # same length and the value of each element is equal to the
674
- # value of the corresponding element in the other list.
675
- #
676
- # `nil` is returned if `other` is not a `List` or `Array`like
677
- # object or if the comparison of two elements returns `nil`.
678
- #
679
- # @see Array#<=>
680
- def <=>(other)
681
- return nil unless \
682
- List === other || (
683
- other.respond_to?(:to_ary ) && other.respond_to?(:length )
684
- )
685
- other = Values >> other
686
- rel_order( other )
687
- end
688
-
689
- # Calls the given block once for each item in the target's
690
- # {#inner_array}, passing the externalization of the item to
691
- # the block.
692
- #
693
- # @see MapWithIndifferentAccess::Values.externalize
694
- #
695
- # @overload each
696
- # @yieldparam item
697
- # @return [List]
698
- #
699
- # @overload each
700
- # @return [Enumerator]
701
- def each
702
- inner_array.each do |item|
703
- item = Values >> item
704
- yield item
705
- end
706
- end
707
-
708
- # @!method assoc(value)
709
- # Searches through elements of the target `List` that are
710
- # also externally represented as `List`s, comparing the
711
- # first item in each of those with `value` using {#==}.
712
- #
713
- # Returns the first item from the target that matches (is
714
- # the first associated `List`) or nil of no match is found.
715
- #
716
- # @return [List, nil]
717
- #
718
- # @see Array#assoc
719
- # @see #rassoc
720
-
721
- # @!method rassoc(value)
722
- # Searches through elements of the target `List` that are
723
- # also externally represented as `List`s, comparing the
724
- # second item in each of those with `value` using {#==}.
725
- #
726
- # Returns the first item from the target that matches (is
727
- # the first associated `List`) or nil of no match is found.
728
- #
729
- # @return [List, nil]
730
- #
731
- # @see Array#rassoc
732
- # @see #assoc
733
-
734
- [ ['assoc', 0 ], ['rassoc', 1 ] ].each do |(method_name,search_col)|
735
- class_eval <<-EOS, __FILE__, __LINE__
736
-
737
- def #{method_name}(value)
738
- result = nil
739
- each do |item|
740
- next unless List === item && item.length > #{search_col}
741
- result = item if item[#{search_col}] == value
742
- end
743
- result
744
- end
745
-
746
- EOS
747
- end
748
-
749
- # Works identically to `Array#bsearch` except that
750
- # externalized values are passed to the block, and the
751
- # externalized result is returned.
752
- #
753
- # @overload bsearch
754
- # @yieldparam x
755
- # @return [Object, nil]
756
- #
757
- # @overload bsearch
758
- # @return [Enumerator]
759
- def bsearch
760
- return to_enum(:bsearch) unless block_given?
761
- inner_result = inner_array.bsearch{ |x| yield Values >> x }
762
- Values >> inner_result
763
- end
764
-
765
- # @!method collect!
766
- # Invokes the given block once for each externalized item
767
- # from the target `List`, replacing the element with the
768
- # internalization of the value returned by the block.
769
- #
770
- # If no block is given, returns an `Enumerator` instead.
771
- #
772
- # @yieldparam extern_item
773
- # @return [List, Enumerable]
774
- #
775
- # @see Enumerable#collect
776
- #
777
- # @overload collect!
778
- # @overload map!
779
-
780
- %w(collect! map!).each do |method_name|
781
- class_eval <<-EOS, __FILE__, __LINE__ + 1
782
-
783
- def #{method_name}
784
- return to_enum( :#{method_name} ) unless block_given?
785
-
786
- inner_array.#{method_name}{ |item|
787
- item = Values >> item
788
- mapped_outer = yield( item )
789
- Values << mapped_outer
790
- }
791
- self
792
- end
793
-
794
- EOS
795
- end
796
-
797
- # Yields every combination of length n of elements from the
798
- # target `List` in the form of a `List` and then returns the
799
- # target `List` itself.
800
- #
801
- # Makes no guarantees about the order in which the
802
- # combinations are yielded.
803
- #
804
- # If no block is given, an `Enumerator` is returned instead.
805
- #
806
- # @overload combination(n)
807
- # @param n [Fixnum]
808
- # @yieldparam combination [List]
809
- # @return [List]
810
- #
811
- # @overload combination(n)
812
- # @param n [Fixnum]
813
- # @return [Enumerator]
814
- def combination(n)
815
- return to_enum( :combination, n ) unless block_given?
816
-
817
- inner_array.combination n do |inner_combos|
818
- yield List.new( inner_combos )
819
- end
820
- self
821
- end
822
-
823
- # Removes `nil` elements from the target `List`.
824
- #
825
- # Returns `nil` if no changes were made. Otherwise returns
826
- # the `List`.
827
- #
828
- # @return [List, nil]
829
- #
830
- # @see #compact
831
- def compact!
832
- inner_array.compact! && self
833
- end
834
-
835
- # Returns a copy of the target `List` with all `nil` items
836
- # removed.
837
- #
838
- # @return [List]
839
- #
840
- # @see #compact!
841
- def compact
842
- result = dup
843
- result.compact!
844
- result
845
- end
846
-
847
- protected
848
-
849
- def rel_order(other_list)
850
- length_rel = length <=> other_list.length
851
- return other_list.reverse_rel_order(self) if length_rel == 1
852
-
853
- rel = 0
854
- zip other_list do |a,b|
855
- rel = a <=> b
856
- break unless rel == 0
857
- end
858
- rel == 0 ? length_rel : rel
859
- end
860
-
861
- def reverse_rel_order(other_list)
862
- rel = rel_order(other_list)
863
- rel.nil? ? nil : -rel
864
- end
865
- end
866
-
867
- end