Class: Accessory::Accessors::BetweenEachAccessor

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

Overview

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

Default constructor used by predecessor accessor

  • Array.new

Instance Method Summary collapse

Methods inherited from Accessory::Accessor

#traverse_or_default

Instance Method Details

#get(data) ⇒ Array

Feeds TraversalPosition::EnumerableBeforeOffsets representing the positions between the elements of data down the accessor chain.

Parameters:

  • data (Enumerable)

    the Enumerable to iterate through

Returns:



52
53
54
55
56
57
58
59
60
# 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

#get_and_update(data) ⇒ Array

Feeds TraversalPosition::EnumerableBeforeOffsets 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.

Parameters:

  • data (Enumerable)

    the Enumerable to iterate through

Returns:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# 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