Class: Accessory::Accessors::BetwixtAccessor

Inherits:
Accessory::Accessor show all
Defined in:
lib/accessory/accessors/betwixt_accessor.rb

Overview

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).

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 SubscriptAccessor would.

Aliases

Default constructor used by predecessor accessor

  • Array.new

Instance Method Summary collapse

Methods inherited from Accessory::Accessor

#traverse_or_default

Constructor Details

#initialize(offset, default: nil) ⇒ BetwixtAccessor

Returns a new instance of BetwixtAccessor.

Parameters:

  • offset (Integer)

    the cursor position (i.e. the index of the element after the cursor)

  • default (Object) (defaults to: nil)

    the default to use if the predecessor accessor passes nil data



33
34
35
36
# File 'lib/accessory/accessors/betwixt_accessor.rb', line 33

def initialize(offset, default: nil)
  super(default)
  @offset = offset
end

Instance Method Details

#get(data) ⇒ Array

Feeds a TraversalPosition::EnumerableBeforeOffset representing the position between the elements of data at @offset down the accessor chain.

Parameters:

  • data (Enumerable)

    the Enumerable to traverse into

Returns:



76
77
78
79
80
81
82
83
84
# 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) ⇒ Array

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.

Parameters:

  • data (Enumerable)

    the Enumerable to traverse into

Returns:



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/accessory/accessors/betwixt_accessor.rb', line 99

def get_and_update(data)
  pos = traverse_or_default(data || [])

  case yield(pos)
  in [result, new_value]
    data ||= []
    data.insert(@offset, new_value)
    [result, data]
  in :pop
    [nil, data]
  end
end