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



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

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.



75
76
77
78
79
80
81
82
83
# File 'lib/accessory/accessors/betwixt_accessor.rb', line 75

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.



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

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