class Accessory::Accessors::BetwixtAccessor
Traverses into a specified cursor-position “between” two elements of an Enumerable
, including the positions at the “edges” (i.e. before the first, or after the last.)
If the provided offset
is positive, this accessor will traverse the position between offset - 1
and offset
; if offset
is negative, this accessor will traverse the position after offset
.
The offset
in this accessor has equivalent semantics to the offset in Array#insert(offset, obj)
.
{Accessors::BetwixtAccessor} can be used with {Lens#put_in} to insert new elements into an Enumerable between the existing ones. If you want to extend an Enumerable
as you would with #push
or #unshift
, this accessor will have better behavior than using {Accessors::SubscriptAccessor} would.
Aliases
-
{Access.betwixt}
-
{Access::FluentHelpers#betwixt} (included in {Lens} and {BoundLens})
Default constructor used by predecessor accessor
-
Array.new
Public Class Methods
@param offset [Integer] the cursor position (i.e. the index of the element after the cursor) @param default [Object] the default to use if the predecessor accessor passes nil
data
Accessory::Accessor::new
# File lib/accessory/accessors/betwixt_accessor.rb, line 33 def initialize(offset, default: nil) super(default) @offset = offset end
Public Instance Methods
@!visibility private
# File lib/accessory/accessors/betwixt_accessor.rb, line 44 def ensure_valid(traversal_result) if traversal_result.kind_of?(Enumerable) traversal_result else [] end end
Feeds a {TraversalPosition::EnumerableBeforeOffset} representing the position between the elements of data
at +@offset+ down the accessor chain.
@param data [Enumerable] the Enumerable
to traverse into @return [Array] the generated {TraversalPosition::EnumerableBeforeOffset}
# File lib/accessory/accessors/betwixt_accessor.rb, line 76 def get(data) pos = traverse_or_default(data || []) if block_given? yield(pos) else pos end end
Feeds a {TraversalPosition::EnumerableBeforeOffset} representing the position between the elements of data
at +@offset+ down the accessor chain, manipulating data
using the result.
If a new element is returned up the accessor chain, the element is inserted at the specified position, using data.insert(@offset, e)
.
If :pop
is returned up the accessor chain, no new element is added.
@param data [Enumerable] the Enumerable
to traverse into @return [Array] a two-element array containing
1. the generated {TraversalPosition::EnumerableBeforeOffset} 2. the new {data}
# File lib/accessory/accessors/betwixt_accessor.rb, line 99 def get_and_update(data) pos = traverse_or_default(data || []) case yield(pos) in [:dirty, result, new_value] data ||= [] data.insert(@offset, new_value) [:dirty, result, data] in :pop [:clean, nil, data] in [:clean, result, _] [:clean, result, data] end end
@!visibility private
# File lib/accessory/accessors/betwixt_accessor.rb, line 39 def inspect_args @offset.inspect end
@!visibility private
# File lib/accessory/accessors/betwixt_accessor.rb, line 53 def traverse(data) nil # return :error unless data.kind_of?(Enumerable) # data_len = data.length # ebo = Accessory::TraversalPosition::EnumerableBeforeOffset.new( # @offset, # (@offset > 0) ? data[@offset - 1] : nil, # (@offset < (data_len - 1)) ? data[@offset + 1] : nil, # is_first: @offset == 0, # is_last: @offset == data_len # ) # [:ok, ebo] end