Class: TrickBag::Enumerables::CompoundEnumerable
- Inherits:
-
Object
- Object
- TrickBag::Enumerables::CompoundEnumerable
- Extended by:
- Meta::Classes
- Includes:
- Enumerable
- Defined in:
- lib/trick_bag/enumerables/compound_enumerable.rb
Overview
For example, for blood types [:a, :b, :ab, :o] and rh [:+, :-], provides an enumerator whose ‘each’ method gives:
- :a, :+
- :a, :-
- :b, :+
- :b, :-
- :ab, :+
- :ab, :-
- :o, :+
- :o, :-
- :a, :-
-
Initialized with enumerables whose ‘each’ method returns an Enumerator when no block is provided.
Guaranteed to follow the order as shown above, that is, each value of the first enumerable will be processed in its entirety before advancing to the next value.
Can be used with an arbitrary number of enumerables.
Constant Summary
Constants included from Meta::Classes
Meta::Classes::VALID_ACCESS_MODES
Instance Attribute Summary collapse
-
#enum_count ⇒ Object
readonly
Returns the value of attribute enum_count.
-
#keys ⇒ Object
readonly
Returns the value of attribute keys.
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
Class Method Summary collapse
-
.array_enumerable(*enumerables) ⇒ Object
Creates a compound enumerable that returns an array whenever ‘each’ is called.
-
.hash_enumerable(keys, *enumerables) ⇒ Object
Creates a compound enumerable that returns a hash whenever ‘each’ is called.
Instance Method Summary collapse
- #each(&block) ⇒ Object
-
#each_multi_enumerable(depth, node, values, &block) ⇒ Object
This method will be called recursively down the list of enumerables.
-
#initialize(mode, keys, *enumerables) ⇒ CompoundEnumerable
constructor
Permissible values are [:yields_arrays, :yields_hashes].
Methods included from Meta::Classes
attr_access, class?, private_attr_accessor, private_attr_reader, private_attr_writer, protected_attr_accessor, protected_attr_reader, protected_attr_writer, undef_class
Constructor Details
#initialize(mode, keys, *enumerables) ⇒ CompoundEnumerable
Permissible values are [:yields_arrays, :yields_hashes].
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 52 def initialize(mode, keys, *enumerables) validate_inputs = ->do raise ArgumentError.new("Mode must be either :yields_arrays or :yields_hashes") unless [:yields_arrays, :yields_hashes].include?(mode) raise ArgumentError.new("Keys not provided") if mode == :yields_hashes && (! keys.is_a?(Array)) raise ArgumentError.new("No enumerables provided") if enumerables.empty? if mode == :yields_hashes && (keys.size != enumerables.size) raise ArgumentError.new("Key array size (#{keys.size}) is different from enumerables size (#{enumerables.size}).") end end validate_inputs.() @enumerables = enumerables @enum_count = enumerables.size @mode = mode @keys = keys end |
Instance Attribute Details
#enum_count ⇒ Object (readonly)
Returns the value of attribute enum_count.
34 35 36 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 34 def enum_count @enum_count end |
#keys ⇒ Object (readonly)
Returns the value of attribute keys.
34 35 36 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 34 def keys @keys end |
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
36 37 38 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 36 def mode @mode end |
Class Method Details
.array_enumerable(*enumerables) ⇒ Object
Creates a compound enumerable that returns an array whenever ‘each’ is called
45 46 47 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 45 def self.array_enumerable(*enumerables) self.new(:yields_arrays, nil, *enumerables) end |
.hash_enumerable(keys, *enumerables) ⇒ Object
Creates a compound enumerable that returns a hash whenever ‘each’ is called
39 40 41 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 39 def self.hash_enumerable(keys, *enumerables) self.new(:yields_hashes, keys, *enumerables) end |
Instance Method Details
#each(&block) ⇒ Object
73 74 75 76 77 78 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 73 def each(&block) return to_enum unless block_given? return if enum_count == 0 initial_value = mode == :yields_arrays ? [] : {} each_multi_enumerable(0, ::TrickBag::Collections::LinkedList.new(*@enumerables).first, initial_value, &block) end |
#each_multi_enumerable(depth, node, values, &block) ⇒ Object
This method will be called recursively down the list of enumerables.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/trick_bag/enumerables/compound_enumerable.rb', line 84 def each_multi_enumerable(depth, node, values, &block) enumerable = node.value is_deepest_enumerable = node.next.nil? as_array = ->(thing) do new_value_array = values + [thing] if is_deepest_enumerable yield *new_value_array else each_multi_enumerable(depth + 1, node.next, new_value_array, &block) end end as_hash = ->(thing) do key = keys[depth] new_values = values.clone new_values[key] = thing if is_deepest_enumerable yield new_values else each_multi_enumerable(depth + 1, node.next, new_values, &block) end new_values end # TODO: Move conditional behavior outside of loop. enumerable.each do |thing| mode == :yields_arrays ? as_array.(thing) : as_hash.(thing) end end |