accessory 0.1.5 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/accessory.rb +2 -2
- data/lib/accessory/access.rb +55 -40
- data/lib/accessory/accessor.rb +43 -50
- data/lib/accessory/accessors/all_accessor.rb +21 -6
- data/lib/accessory/accessors/attribute_accessor.rb +15 -11
- data/lib/accessory/accessors/between_each_accessor.rb +22 -9
- data/lib/accessory/accessors/betwixt_accessor.rb +31 -19
- data/lib/accessory/accessors/filter_accessor.rb +20 -6
- data/lib/accessory/accessors/first_accessor.rb +17 -11
- data/lib/accessory/accessors/instance_variable_accessor.rb +12 -10
- data/lib/accessory/accessors/last_accessor.rb +17 -11
- data/lib/accessory/accessors/subscript_accessor.rb +19 -12
- data/lib/accessory/bound_lens.rb +139 -0
- data/lib/accessory/lens.rb +203 -75
- data/lib/accessory/traversal_position/enumerable_before_offset.rb +5 -5
- data/lib/accessory/version.rb +1 -1
- metadata +3 -3
- data/lib/accessory/lens_path.rb +0 -219
@@ -5,21 +5,25 @@ require 'accessory/traversal_position/enumerable_before_offset'
|
|
5
5
|
# Traverses the positions "between" the elements of an +Enumerable+, including
|
6
6
|
# the positions at the "edges" (i.e. before the first, and after the last.)
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# BetweenEachAccessor can be used with {Lens#put_in} to insert new
|
9
9
|
# elements into an Enumerable between the existing ones.
|
10
10
|
#
|
11
11
|
# *Aliases*
|
12
12
|
# * {Access.between_each}
|
13
|
-
# * {Access::FluentHelpers#between_each} (included in {
|
13
|
+
# * {Access::FluentHelpers#between_each} (included in {Lens} and {BoundLens})
|
14
14
|
#
|
15
15
|
# <b>Default constructor</b> used by predecessor accessor
|
16
16
|
#
|
17
17
|
# * +Array.new+
|
18
18
|
|
19
|
-
class Accessory::BetweenEachAccessor < Accessory::Accessor
|
19
|
+
class Accessory::Accessors::BetweenEachAccessor < Accessory::Accessor
|
20
20
|
# @!visibility private
|
21
|
-
def
|
22
|
-
|
21
|
+
def ensure_valid(traversal_result)
|
22
|
+
if traversal_result.kind_of?(Enumerable)
|
23
|
+
traversal_result
|
24
|
+
else
|
25
|
+
[]
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
# @!visibility private
|
@@ -46,7 +50,7 @@ class Accessory::BetweenEachAccessor < Accessory::Accessor
|
|
46
50
|
# @param data [Enumerable] the +Enumerable+ to iterate through
|
47
51
|
# @return [Array] the generated {TraversalPosition::EnumerableBeforeOffset}s
|
48
52
|
def get(data)
|
49
|
-
positions =
|
53
|
+
positions = traverse_or_default(data || [])
|
50
54
|
|
51
55
|
if block_given?
|
52
56
|
positions.map{ |rec| yield(rec) }
|
@@ -71,15 +75,20 @@ class Accessory::BetweenEachAccessor < Accessory::Accessor
|
|
71
75
|
def get_and_update(data)
|
72
76
|
results = []
|
73
77
|
new_data = []
|
78
|
+
dirty = false
|
74
79
|
|
75
|
-
positions =
|
80
|
+
positions = traverse_or_default(data || [])
|
76
81
|
|
77
82
|
positions.each do |pos|
|
78
83
|
case yield(pos)
|
79
|
-
in [result,
|
84
|
+
in [:clean, result, _]
|
85
|
+
results.push(result)
|
86
|
+
in [:dirty, result, new_value]
|
80
87
|
new_data.push(new_value)
|
81
88
|
results.push(result)
|
89
|
+
dirty = true
|
82
90
|
in :pop
|
91
|
+
# ok
|
83
92
|
end
|
84
93
|
|
85
94
|
unless pos.last?
|
@@ -87,6 +96,10 @@ class Accessory::BetweenEachAccessor < Accessory::Accessor
|
|
87
96
|
end
|
88
97
|
end
|
89
98
|
|
90
|
-
|
99
|
+
if dirty
|
100
|
+
[:dirty, results, new_data]
|
101
|
+
else
|
102
|
+
[:clean, results, data]
|
103
|
+
end
|
91
104
|
end
|
92
105
|
end
|
@@ -13,20 +13,21 @@ require 'accessory/traversal_position/enumerable_before_offset'
|
|
13
13
|
# The +offset+ in this accessor has equivalent semantics to the offset in
|
14
14
|
# <tt>Array#insert(offset, obj)</tt>.
|
15
15
|
#
|
16
|
-
# {BetwixtAccessor} can be used with {
|
16
|
+
# {Accessors::BetwixtAccessor} can be used with {Lens#put_in} to insert new
|
17
17
|
# elements into an Enumerable between the existing ones. If you want to extend
|
18
18
|
# an +Enumerable+ as you would with <tt>#push</tt> or <tt>#unshift</tt>, this
|
19
|
-
# accessor will have better behavior than using {SubscriptAccessor}
|
19
|
+
# accessor will have better behavior than using {Accessors::SubscriptAccessor}
|
20
|
+
# would.
|
20
21
|
#
|
21
22
|
# *Aliases*
|
22
23
|
# * {Access.betwixt}
|
23
|
-
# * {Access::FluentHelpers#betwixt} (included in {
|
24
|
+
# * {Access::FluentHelpers#betwixt} (included in {Lens} and {BoundLens})
|
24
25
|
#
|
25
26
|
# <b>Default constructor</b> used by predecessor accessor
|
26
27
|
#
|
27
28
|
# * +Array.new+
|
28
29
|
|
29
|
-
class Accessory::BetwixtAccessor < Accessory::Accessor
|
30
|
+
class Accessory::Accessors::BetwixtAccessor < Accessory::Accessor
|
30
31
|
# @param offset [Integer] the cursor position (i.e. the index of the element after the cursor)
|
31
32
|
# @param default [Object] the default to use if the predecessor accessor passes +nil+ data
|
32
33
|
def initialize(offset, default: nil)
|
@@ -40,21 +41,30 @@ class Accessory::BetwixtAccessor < Accessory::Accessor
|
|
40
41
|
end
|
41
42
|
|
42
43
|
# @!visibility private
|
43
|
-
def
|
44
|
-
|
44
|
+
def ensure_valid(traversal_result)
|
45
|
+
if traversal_result.kind_of?(Enumerable)
|
46
|
+
traversal_result
|
47
|
+
else
|
48
|
+
[]
|
49
|
+
end
|
45
50
|
end
|
46
51
|
|
47
52
|
# @!visibility private
|
48
53
|
def traverse(data)
|
49
|
-
|
54
|
+
nil
|
55
|
+
# return :error unless data.kind_of?(Enumerable)
|
56
|
+
|
57
|
+
# data_len = data.length
|
58
|
+
|
59
|
+
# ebo = Accessory::TraversalPosition::EnumerableBeforeOffset.new(
|
60
|
+
# @offset,
|
61
|
+
# (@offset > 0) ? data[@offset - 1] : nil,
|
62
|
+
# (@offset < (data_len - 1)) ? data[@offset + 1] : nil,
|
63
|
+
# is_first: @offset == 0,
|
64
|
+
# is_last: @offset == data_len
|
65
|
+
# )
|
50
66
|
|
51
|
-
|
52
|
-
@offset,
|
53
|
-
(@offset > 0) ? data[@offset - 1] : nil,
|
54
|
-
(@offset < (data_len - 1)) ? data[@offset + 1] : nil,
|
55
|
-
is_first: @offset == 0,
|
56
|
-
is_last: @offset == data_len
|
57
|
-
)
|
67
|
+
# [:ok, ebo]
|
58
68
|
end
|
59
69
|
|
60
70
|
# Feeds a {TraversalPosition::EnumerableBeforeOffset} representing the
|
@@ -64,7 +74,7 @@ class Accessory::BetwixtAccessor < Accessory::Accessor
|
|
64
74
|
# @param data [Enumerable] the +Enumerable+ to traverse into
|
65
75
|
# @return [Array] the generated {TraversalPosition::EnumerableBeforeOffset}
|
66
76
|
def get(data)
|
67
|
-
pos =
|
77
|
+
pos = traverse_or_default(data || [])
|
68
78
|
|
69
79
|
if block_given?
|
70
80
|
yield(pos)
|
@@ -87,15 +97,17 @@ class Accessory::BetwixtAccessor < Accessory::Accessor
|
|
87
97
|
# 1. the generated {TraversalPosition::EnumerableBeforeOffset}
|
88
98
|
# 2. the new {data}
|
89
99
|
def get_and_update(data)
|
90
|
-
pos =
|
100
|
+
pos = traverse_or_default(data || [])
|
91
101
|
|
92
102
|
case yield(pos)
|
93
|
-
in [result, new_value]
|
103
|
+
in [:dirty, result, new_value]
|
94
104
|
data ||= []
|
95
105
|
data.insert(@offset, new_value)
|
96
|
-
[result, data]
|
106
|
+
[:dirty, result, data]
|
97
107
|
in :pop
|
98
|
-
[nil, data]
|
108
|
+
[:clean, nil, data]
|
109
|
+
in [:clean, result, _]
|
110
|
+
[:clean, result, data]
|
99
111
|
end
|
100
112
|
end
|
101
113
|
end
|
@@ -6,7 +6,7 @@ require 'accessory/accessor'
|
|
6
6
|
#
|
7
7
|
# *Aliases*
|
8
8
|
# * {Access.filter}
|
9
|
-
# * {Access::FluentHelpers#filter} (included in {
|
9
|
+
# * {Access::FluentHelpers#filter} (included in {Lens} and {BoundLens})
|
10
10
|
#
|
11
11
|
# *Equivalents* in Elixir's {https://hexdocs.pm/elixir/Access.html +Access+} module
|
12
12
|
# * {https://hexdocs.pm/elixir/Access.html#filter/1 +Access.filter/1+}
|
@@ -15,7 +15,7 @@ require 'accessory/accessor'
|
|
15
15
|
#
|
16
16
|
# * +Array.new+
|
17
17
|
|
18
|
-
class Accessory::FilterAccessor < Accessory::Accessor
|
18
|
+
class Accessory::Accessors::FilterAccessor < Accessory::Accessor
|
19
19
|
# Returns a new instance of {FilterAccessor}.
|
20
20
|
#
|
21
21
|
# The predicate function may be passed in as either a positional argument,
|
@@ -34,8 +34,12 @@ class Accessory::FilterAccessor < Accessory::Accessor
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# @!visibility private
|
37
|
-
def
|
38
|
-
|
37
|
+
def ensure_valid(traversal_result)
|
38
|
+
if traversal_result.kind_of?(Enumerable)
|
39
|
+
traversal_result
|
40
|
+
else
|
41
|
+
[]
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
# Feeds each element of +data+ matching the predicate down the accessor chain,
|
@@ -61,6 +65,7 @@ class Accessory::FilterAccessor < Accessory::Accessor
|
|
61
65
|
def get_and_update(data)
|
62
66
|
results = []
|
63
67
|
new_data = []
|
68
|
+
dirty = false
|
64
69
|
|
65
70
|
(data || []).each do |pos|
|
66
71
|
unless @pred.call(pos)
|
@@ -69,14 +74,23 @@ class Accessory::FilterAccessor < Accessory::Accessor
|
|
69
74
|
end
|
70
75
|
|
71
76
|
case yield(pos)
|
72
|
-
in [result,
|
77
|
+
in [:clean, result, _]
|
78
|
+
results.push(result)
|
79
|
+
new_data.push(pos)
|
80
|
+
in [:dirty, result, new_value]
|
73
81
|
results.push(result)
|
74
82
|
new_data.push(new_value)
|
83
|
+
dirty = true
|
75
84
|
in :pop
|
76
85
|
results.push(pos)
|
86
|
+
dirty = true
|
77
87
|
end
|
78
88
|
end
|
79
89
|
|
80
|
-
|
90
|
+
if dirty
|
91
|
+
[:dirty, results, new_data]
|
92
|
+
else
|
93
|
+
[:clean, results, data]
|
94
|
+
end
|
81
95
|
end
|
82
96
|
end
|
@@ -4,21 +4,25 @@ require 'accessory/accessor'
|
|
4
4
|
# Traverses into the "first" element within an +Enumerable+, using
|
5
5
|
# <tt>#first</tt>.
|
6
6
|
#
|
7
|
-
# This accessor can be preferable to {SubscriptAccessor} for objects
|
8
|
-
# are not subscriptable, e.g.
|
7
|
+
# This accessor can be preferable to {Accessors::SubscriptAccessor} for objects
|
8
|
+
# that are not subscriptable, e.g. +Range+.
|
9
9
|
#
|
10
10
|
# *Aliases*
|
11
11
|
# * {Access.first}
|
12
|
-
# * {Access::FluentHelpers#first} (included in {
|
12
|
+
# * {Access::FluentHelpers#first} (included in {Lens} and {BoundLens})
|
13
13
|
#
|
14
14
|
# <b>Default constructor</b> used by predecessor accessor
|
15
15
|
#
|
16
16
|
# * +Array.new+
|
17
17
|
|
18
|
-
class Accessory::FirstAccessor < Accessory::Accessor
|
18
|
+
class Accessory::Accessors::FirstAccessor < Accessory::Accessor
|
19
19
|
# @!visibility private
|
20
|
-
def
|
21
|
-
|
20
|
+
def ensure_valid(traversal_result)
|
21
|
+
if traversal_result.kind_of?(Enumerable)
|
22
|
+
traversal_result
|
23
|
+
else
|
24
|
+
[]
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
# @!visibility private
|
@@ -33,7 +37,7 @@ class Accessory::FirstAccessor < Accessory::Accessor
|
|
33
37
|
# @param data [Object] the object to traverse
|
34
38
|
# @return [Object] the value derived from the rest of the accessor chain
|
35
39
|
def get(data)
|
36
|
-
value =
|
40
|
+
value = traverse_or_default(data)
|
37
41
|
|
38
42
|
if block_given?
|
39
43
|
yield(value)
|
@@ -51,19 +55,21 @@ class Accessory::FirstAccessor < Accessory::Accessor
|
|
51
55
|
# @param data [Object] the object to traverse
|
52
56
|
# @return [Array] a two-element array containing 1. the original value found; and 2. the result value from the accessor chain
|
53
57
|
def get_and_update(data)
|
54
|
-
old_value =
|
58
|
+
old_value = traverse_or_default(data)
|
55
59
|
|
56
60
|
case yield(old_value)
|
57
|
-
in [result,
|
61
|
+
in [:clean, result, _]
|
62
|
+
[:clean, result, data]
|
63
|
+
in [:dirty, result, new_value]
|
58
64
|
if data.respond_to?(:"first=")
|
59
65
|
data.first = new_value
|
60
66
|
else
|
61
67
|
data[0] = new_value
|
62
68
|
end
|
63
|
-
[result, data]
|
69
|
+
[:dirty, result, data]
|
64
70
|
in :pop
|
65
71
|
data.delete_at(0)
|
66
|
-
[old_value, data]
|
72
|
+
[:dirty, old_value, data]
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
@@ -8,14 +8,14 @@ require 'accessory/accessor'
|
|
8
8
|
#
|
9
9
|
# *Aliases*
|
10
10
|
# * {Access.ivar}
|
11
|
-
# * {Access::FluentHelpers#ivar} (included in {
|
11
|
+
# * {Access::FluentHelpers#ivar} (included in {Lens} and {BoundLens})
|
12
12
|
#
|
13
13
|
# <b>Default constructor</b> used by predecessor accessor
|
14
14
|
#
|
15
15
|
# * +Object.new+
|
16
16
|
|
17
|
-
class Accessory::InstanceVariableAccessor < Accessory::Accessor
|
18
|
-
# @param
|
17
|
+
class Accessory::Accessors::InstanceVariableAccessor < Accessory::Accessor
|
18
|
+
# @param ivar_name [Symbol] the instance-variable name
|
19
19
|
# @param default [Object] the default to use if the predecessor accessor passes +nil+ data
|
20
20
|
def initialize(ivar_name, default: nil)
|
21
21
|
super(default)
|
@@ -33,8 +33,8 @@ class Accessory::InstanceVariableAccessor < Accessory::Accessor
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# @!visibility private
|
36
|
-
def
|
37
|
-
|
36
|
+
def ensure_valid(traversal_result)
|
37
|
+
traversal_result || Object.new
|
38
38
|
end
|
39
39
|
|
40
40
|
# @!visibility private
|
@@ -47,7 +47,7 @@ class Accessory::InstanceVariableAccessor < Accessory::Accessor
|
|
47
47
|
# @param data [Object] the object to traverse
|
48
48
|
# @return [Object] the value derived from the rest of the accessor chain
|
49
49
|
def get(data)
|
50
|
-
value =
|
50
|
+
value = traverse_or_default(data)
|
51
51
|
|
52
52
|
if block_given?
|
53
53
|
yield(value)
|
@@ -67,15 +67,17 @@ class Accessory::InstanceVariableAccessor < Accessory::Accessor
|
|
67
67
|
# @param data [Object] the object to traverse
|
68
68
|
# @return [Array] a two-element array containing 1. the original value found; and 2. the result value from the accessor chain
|
69
69
|
def get_and_update(data)
|
70
|
-
value =
|
70
|
+
value = traverse_or_default(data)
|
71
71
|
|
72
72
|
case yield(value)
|
73
|
-
in [result,
|
73
|
+
in [:clean, result, _]
|
74
|
+
[:clean, result, data]
|
75
|
+
in [:dirty, result, new_value]
|
74
76
|
data.instance_variable_set(@ivar_name, new_value)
|
75
|
-
[result, data]
|
77
|
+
[:dirty, result, data]
|
76
78
|
in :pop
|
77
79
|
data.remove_instance_variable(@ivar_name)
|
78
|
-
[value, data]
|
80
|
+
[:dirty, value, data]
|
79
81
|
end
|
80
82
|
end
|
81
83
|
end
|
@@ -4,21 +4,25 @@ require 'accessory/accessor'
|
|
4
4
|
# Traverses into the "last" element within an +Enumerable+, using
|
5
5
|
# <tt>#last</tt>.
|
6
6
|
#
|
7
|
-
# This accessor can be preferable to {SubscriptAccessor} for objects
|
8
|
-
# are not subscriptable, e.g.
|
7
|
+
# This accessor can be preferable to {Accessors::SubscriptAccessor} for objects
|
8
|
+
# that are not subscriptable, e.g. +Range+.
|
9
9
|
#
|
10
10
|
# *Aliases*
|
11
11
|
# * {Access.last}
|
12
|
-
# * {Access::FluentHelpers#last} (included in {
|
12
|
+
# * {Access::FluentHelpers#last} (included in {Lens} and {BoundLens})
|
13
13
|
#
|
14
14
|
# <b>Default constructor</b> used by predecessor accessor
|
15
15
|
#
|
16
16
|
# * +Array.new+
|
17
17
|
|
18
|
-
class Accessory::LastAccessor < Accessory::Accessor
|
18
|
+
class Accessory::Accessors::LastAccessor < Accessory::Accessor
|
19
19
|
# @!visibility private
|
20
|
-
def
|
21
|
-
|
20
|
+
def ensure_valid(traversal_result)
|
21
|
+
if traversal_result.kind_of?(Enumerable)
|
22
|
+
traversal_result
|
23
|
+
else
|
24
|
+
[]
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
# @!visibility private
|
@@ -33,7 +37,7 @@ class Accessory::LastAccessor < Accessory::Accessor
|
|
33
37
|
# @param data [Object] the object to traverse
|
34
38
|
# @return [Object] the value derived from the rest of the accessor chain
|
35
39
|
def get(data)
|
36
|
-
value =
|
40
|
+
value = traverse_or_default(data)
|
37
41
|
|
38
42
|
if block_given?
|
39
43
|
yield(value)
|
@@ -51,19 +55,21 @@ class Accessory::LastAccessor < Accessory::Accessor
|
|
51
55
|
# @param data [Object] the object to traverse
|
52
56
|
# @return [Array] a two-element array containing 1. the original value found; and 2. the result value from the accessor chain
|
53
57
|
def get_and_update(data)
|
54
|
-
old_value =
|
58
|
+
old_value = traverse_or_default(data)
|
55
59
|
|
56
60
|
case yield(old_value)
|
57
|
-
in [result,
|
61
|
+
in [:clean, result, _]
|
62
|
+
[:clean, result, data]
|
63
|
+
in [:dirty, result, new_value]
|
58
64
|
if data.respond_to?(:"last=")
|
59
65
|
data.last = new_value
|
60
66
|
else
|
61
67
|
data[-1] = new_value
|
62
68
|
end
|
63
|
-
[result, data]
|
69
|
+
[:dirty, result, data]
|
64
70
|
in :pop
|
65
71
|
data.delete_at(-1)
|
66
|
-
[old_value, data]
|
72
|
+
[:dirty, old_value, data]
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
@@ -7,9 +7,10 @@ require 'accessory/accessor'
|
|
7
7
|
#
|
8
8
|
# *Aliases*
|
9
9
|
# * {Access.subscript}
|
10
|
-
# * {Access::FluentHelpers#subscript} (included in {
|
11
|
-
# * {Access::FluentHelpers#[]} (included in {
|
12
|
-
# * just passing a +key+ will also work, when +not(key.kind_of?(Accessor))+
|
10
|
+
# * {Access::FluentHelpers#subscript} (included in {Lens} and {BoundLens})
|
11
|
+
# * {Access::FluentHelpers#[]} (included in {Lens} and {BoundLens})
|
12
|
+
# * just passing a +key+ will also work, when +not(key.kind_of?(Accessor))+
|
13
|
+
# (this is a special case in {Lens#initialize})
|
13
14
|
#
|
14
15
|
# *Equivalents* in Elixir's {https://hexdocs.pm/elixir/Access.html +Access+} module
|
15
16
|
# * {https://hexdocs.pm/elixir/Access.html#at/1 +Access.at/1+}
|
@@ -28,9 +29,9 @@ require 'accessory/accessor'
|
|
28
29
|
# # default-constructs a Hash, not an Array
|
29
30
|
# [].lens[0][0].put_in(1) # => [{0=>1}]
|
30
31
|
#
|
31
|
-
# Other accessors ({FirstAccessor}, {BetwixtAccessor}, etc.) may fit your expectations more closely for +Array+ traversal.
|
32
|
+
# Other accessors ({Accessors::FirstAccessor}, {Accessors::BetwixtAccessor}, etc.) may fit your expectations more closely for +Array+ traversal.
|
32
33
|
|
33
|
-
class Accessory::SubscriptAccessor < Accessory::Accessor
|
34
|
+
class Accessory::Accessors::SubscriptAccessor < Accessory::Accessor
|
34
35
|
# @!visibility private
|
35
36
|
def initialize(key, **kwargs)
|
36
37
|
super(**kwargs)
|
@@ -53,8 +54,12 @@ class Accessory::SubscriptAccessor < Accessory::Accessor
|
|
53
54
|
end
|
54
55
|
|
55
56
|
# @!visibility private
|
56
|
-
def
|
57
|
-
|
57
|
+
def ensure_valid(traversal_result)
|
58
|
+
if traversal_result.respond_to?(:[])
|
59
|
+
traversal_result
|
60
|
+
else
|
61
|
+
{}
|
62
|
+
end
|
58
63
|
end
|
59
64
|
|
60
65
|
# @!visibility private
|
@@ -67,7 +72,7 @@ class Accessory::SubscriptAccessor < Accessory::Accessor
|
|
67
72
|
# @param data [Enumerable] the +Enumerable+ to index into
|
68
73
|
# @return [Object] the value derived from the rest of the accessor chain
|
69
74
|
def get(data)
|
70
|
-
value =
|
75
|
+
value = traverse_or_default(data)
|
71
76
|
|
72
77
|
if block_given?
|
73
78
|
yield(value)
|
@@ -84,15 +89,17 @@ class Accessory::SubscriptAccessor < Accessory::Accessor
|
|
84
89
|
# @param data [Enumerable] the +Enumerable+ to index into
|
85
90
|
# @return [Array] a two-element array containing 1. the original value found; and 2. the result value from the accessor chain
|
86
91
|
def get_and_update(data)
|
87
|
-
value =
|
92
|
+
value = traverse_or_default(data)
|
88
93
|
|
89
94
|
case yield(value)
|
90
|
-
in [result,
|
95
|
+
in [:clean, result, _]
|
96
|
+
[:clean, result, data]
|
97
|
+
in [:dirty, result, new_value]
|
91
98
|
data[@key] = new_value
|
92
|
-
[result, data]
|
99
|
+
[:dirty, result, data]
|
93
100
|
in :pop
|
94
101
|
data.delete(@key)
|
95
|
-
[value, data]
|
102
|
+
[:dirty, value, data]
|
96
103
|
end
|
97
104
|
end
|
98
105
|
end
|