class Accessory::Accessors::BetweenEachAccessor
Traverses the positions “between” the elements of an Enumerable
, including the positions at the “edges” (i.e. before the first, and after the last.)
BetweenEachAccessor
can be used with {Lens#put_in} to insert new elements into an Enumerable between the existing ones.
Aliases
-
{Access.between_each}
-
{Access::FluentHelpers#between_each} (included in {Lens} and {BoundLens})
Default constructor used by predecessor accessor
-
Array.new
Public Instance Methods
@!visibility private
# File lib/accessory/accessors/between_each_accessor.rb, line 21 def ensure_valid(traversal_result) if traversal_result.kind_of?(Enumerable) traversal_result else [] end end
Feeds {TraversalPosition::EnumerableBeforeOffset}s representing the positions between the elements of data
down the accessor chain.
@param data [Enumerable] the Enumerable
to iterate through @return [Array] the generated {TraversalPosition::EnumerableBeforeOffset}s
# File lib/accessory/accessors/between_each_accessor.rb, line 52 def get(data) positions = traverse_or_default(data || []) if block_given? positions.map{ |rec| yield(rec) } else positions end end
Feeds {TraversalPosition::EnumerableBeforeOffset}s representing the positions between the elements of data
down the accessor chain, manipulating data
using the results.
If a new element is returned up the accessor chain, the element is inserted between the existing elements.
If :pop
is returned up the accessor chain, no new element is added.
@param data [Enumerable] the Enumerable
to iterate through @return [Array] a two-element array containing
1. the {TraversalPosition::EnumerableBeforeOffset}s 2. the new {data}
# File lib/accessory/accessors/between_each_accessor.rb, line 75 def get_and_update(data) results = [] new_data = [] dirty = false positions = traverse_or_default(data || []) positions.each do |pos| case yield(pos) in [:clean, result, _] results.push(result) in [:dirty, result, new_value] new_data.push(new_value) results.push(result) dirty = true in :pop # ok end unless pos.last? new_data.push(pos.elem_after) end end if dirty [:dirty, results, new_data] else [:clean, results, data] end end
@!visibility private
# File lib/accessory/accessors/between_each_accessor.rb, line 30 def inspect_args; nil; end
@!visibility private
# File lib/accessory/accessors/between_each_accessor.rb, line 33 def traverse(data) data_len = data.length positions = [ (0..data_len).to_a, data + [nil], [nil] + data ] positions.transpose.map do |(i, b, a)| Accessory::TraversalPosition::EnumerableBeforeOffset.new(i, b, a, is_first: i == 0, is_last: i == data_len) end end