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

Default constructor used by predecessor accessor

Public Class Methods

new(offset, default: nil) click to toggle source

@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

Calls superclass method 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

ensure_valid(traversal_result) click to toggle source

@!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
get(data) { |pos| ... } click to toggle source

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
get_and_update(data) { |pos| ... } click to toggle source

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
inspect_args() click to toggle source

@!visibility private

# File lib/accessory/accessors/betwixt_accessor.rb, line 39
def inspect_args
  @offset.inspect
end
traverse(data) click to toggle source

@!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