accessory 0.1.2 → 0.1.7
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 +3 -3
- data/lib/accessory/access.rb +67 -21
- data/lib/accessory/accessor.rb +173 -13
- data/lib/accessory/accessors/all_accessor.rb +35 -3
- data/lib/accessory/accessors/attribute_accessor.rb +60 -8
- data/lib/accessory/accessors/between_each_accessor.rb +48 -8
- data/lib/accessory/accessors/betwixt_accessor.rb +75 -17
- data/lib/accessory/accessors/filter_accessor.rb +46 -5
- data/lib/accessory/accessors/first_accessor.rb +44 -7
- data/lib/accessory/accessors/instance_variable_accessor.rb +41 -8
- data/lib/accessory/accessors/last_accessor.rb +44 -7
- data/lib/accessory/accessors/subscript_accessor.rb +57 -6
- data/lib/accessory/bound_lens.rb +139 -0
- data/lib/accessory/lens.rb +197 -26
- data/lib/accessory/traversal_position/enumerable_at_offset.rb +28 -0
- data/lib/accessory/traversal_position/enumerable_before_offset.rb +55 -0
- data/lib/accessory/version.rb +1 -1
- metadata +5 -4
- data/lib/accessory/array_cursor_position.rb +0 -18
- data/lib/accessory/lens_path.rb +0 -150
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f4517af7f1ae501a9dea6721f8dd0966a85c2fd9e8ada3d1d444f8b58cb297e
|
4
|
+
data.tar.gz: 4e8bcc0130b9cb5078779642cc0e81f4d4121ac6275ead2fe7a5decd873a5047
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 295b43b1f100522c1dcc9e659acbcf174a9725c38448d68b8eb3be10603b9ad9df643f82dced994849616d194ccef080697febc3f934440b45420eae8229fa31
|
7
|
+
data.tar.gz: 5d9d93d0a17668ba39313dd8151cf7324a562df362fbbeb0a34bdc6c24b2dc7a8996f36f8e0b1be1c0d489dafc435f645e1b8a4348e3a080bdd66e9efe5dbc61
|
data/lib/accessory.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Accessory; end
|
2
2
|
|
3
3
|
require 'accessory/version'
|
4
|
-
require 'accessory/lens_path'
|
5
4
|
require 'accessory/lens'
|
5
|
+
require 'accessory/bound_lens'
|
6
6
|
require 'accessory/access'
|
7
7
|
|
8
8
|
module Accessory
|
9
9
|
refine ::Object do
|
10
|
-
def lens
|
11
|
-
::Accessory::
|
10
|
+
def lens(...)
|
11
|
+
::Accessory::BoundLens.on(self, ...)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
data/lib/accessory/access.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Accessory; end
|
2
2
|
|
3
3
|
require 'accessory/accessors/subscript_accessor'
|
4
|
-
require 'accessory/accessors/
|
4
|
+
require 'accessory/accessors/attribute_accessor'
|
5
5
|
require 'accessory/accessors/filter_accessor'
|
6
6
|
require 'accessory/accessors/instance_variable_accessor'
|
7
7
|
require 'accessory/accessors/betwixt_accessor'
|
@@ -10,91 +10,137 @@ require 'accessory/accessors/all_accessor'
|
|
10
10
|
require 'accessory/accessors/first_accessor'
|
11
11
|
require 'accessory/accessors/last_accessor'
|
12
12
|
|
13
|
+
##
|
14
|
+
# A set of convenient module-function helpers to use with <tt>Lens[...]</tt>.
|
15
|
+
#
|
16
|
+
# These functions aren't very convenient unless you
|
17
|
+
#
|
18
|
+
# include Accessory
|
19
|
+
|
13
20
|
module Accessory::Access
|
14
|
-
|
15
|
-
|
21
|
+
# (see Accessory::Accessors::SubscriptAccessor)
|
22
|
+
def self.subscript(...)
|
23
|
+
Accessory::Accessors::SubscriptAccessor.new(...)
|
24
|
+
end
|
25
|
+
|
26
|
+
# (see Accessory::Accessors::AttributeAccessor)
|
27
|
+
def self.attr(...)
|
28
|
+
Accessory::Accessors::AttributeAccessor.new(...)
|
16
29
|
end
|
17
30
|
|
31
|
+
# (see Accessory::Accessors::InstanceVariableAccessor)
|
18
32
|
def self.ivar(...)
|
19
|
-
Accessory::InstanceVariableAccessor.new(...)
|
33
|
+
Accessory::Accessors::InstanceVariableAccessor.new(...)
|
20
34
|
end
|
21
35
|
|
36
|
+
# (see Accessory::Accessors::BetwixtAccessor)
|
22
37
|
def self.betwixt(...)
|
23
|
-
Accessory::BetwixtAccessor.new(...)
|
38
|
+
Accessory::Accessors::BetwixtAccessor.new(...)
|
24
39
|
end
|
25
40
|
|
41
|
+
# Alias for +Accessory::Accessors::Access.betwixt(0)+. See {Access.betwixt}
|
26
42
|
def self.before_first
|
27
43
|
self.betwixt(0)
|
28
44
|
end
|
29
45
|
|
46
|
+
# Alias for +Accessory::Accessors::Access.betwixt(-1)+. See {Access.betwixt}
|
30
47
|
def self.after_last
|
31
48
|
self.betwixt(-1)
|
32
49
|
end
|
33
50
|
|
51
|
+
# (see Accessory::Accessors::BetweenEachAccessor)
|
34
52
|
def self.between_each
|
35
|
-
Accessory::BetweenEachAccessor.new
|
53
|
+
Accessory::Accessors::BetweenEachAccessor.new
|
36
54
|
end
|
37
55
|
|
56
|
+
# (see Accessory::Accessors::AllAccessor)
|
38
57
|
def self.all
|
39
|
-
Accessory::AllAccessor.new
|
58
|
+
Accessory::Accessors::AllAccessor.new
|
40
59
|
end
|
41
60
|
|
61
|
+
# (see Accessory::Accessors::FirstAccessor)
|
42
62
|
def self.first
|
43
|
-
Accessory::FirstAccessor.new
|
63
|
+
Accessory::Accessors::FirstAccessor.new
|
44
64
|
end
|
45
65
|
|
66
|
+
# (see Accessory::Accessors::LastAccessor)
|
46
67
|
def self.last
|
47
|
-
Accessory::LastAccessor.new
|
68
|
+
Accessory::Accessors::LastAccessor.new
|
48
69
|
end
|
49
70
|
|
71
|
+
# (see Accessory::Accessors::FilterAccessor)
|
50
72
|
def self.filter(&pred)
|
51
|
-
Accessory::FilterAccessor.new(pred)
|
73
|
+
Accessory::Accessors::FilterAccessor.new(pred)
|
52
74
|
end
|
53
75
|
end
|
54
76
|
|
77
|
+
##
|
78
|
+
# A set of convenient "fluent API" builder methods
|
79
|
+
# that get mixed into {Lens} and {BoundLens}.
|
80
|
+
#
|
81
|
+
# These do the same thing as the {Access} helper of the same name, but
|
82
|
+
# wrap the resulting accessor in a call to <tt>#then</tt>, deriving a new
|
83
|
+
# {Lens} or {BoundLens} from the addition of the accessor.
|
84
|
+
|
55
85
|
module Accessory::Access::FluentHelpers
|
86
|
+
# (see Accessory::Accessors::SubscriptAccessor)
|
87
|
+
def subscript(...)
|
88
|
+
self.then(Accessory::Accessors::SubscriptAccessor.new(...))
|
89
|
+
end
|
90
|
+
|
91
|
+
# Alias for {#subscript}
|
56
92
|
def [](...)
|
57
|
-
self.then(Accessory::SubscriptAccessor.new(...))
|
93
|
+
self.then(Accessory::Accessors::SubscriptAccessor.new(...))
|
58
94
|
end
|
59
95
|
|
60
|
-
|
61
|
-
|
96
|
+
# (see Accessory::Accessors::AttributeAccessor)
|
97
|
+
def attr(...)
|
98
|
+
self.then(Accessory::Accessors::AttributeAccessor.new(...))
|
62
99
|
end
|
63
100
|
|
101
|
+
# (see Accessory::Accessors::InstanceVariableAccessor)
|
64
102
|
def ivar(...)
|
65
|
-
self.then(Accessory::InstanceVariableAccessor.new(...))
|
103
|
+
self.then(Accessory::Accessors::InstanceVariableAccessor.new(...))
|
66
104
|
end
|
67
105
|
|
106
|
+
# (see Accessory::Accessors::BetwixtAccessor)
|
68
107
|
def betwixt(...)
|
69
|
-
self.then(Accessory::BetwixtAccessor.new(...))
|
108
|
+
self.then(Accessory::Accessors::BetwixtAccessor.new(...))
|
70
109
|
end
|
71
110
|
|
111
|
+
# Alias for +#betwixt(0)+. See {#betwixt}
|
72
112
|
def before_first
|
73
113
|
self.betwixt(0)
|
74
114
|
end
|
75
115
|
|
116
|
+
# Alias for +#betwixt(-1)+. See {#betwixt}
|
76
117
|
def after_last
|
77
118
|
self.betwixt(-1)
|
78
119
|
end
|
79
120
|
|
121
|
+
# (see Accessory::Accessors::BetweenEachAccessor)
|
80
122
|
def between_each
|
81
|
-
self.then(Accessory::BetweenEachAccessor.new)
|
123
|
+
self.then(Accessory::Accessors::BetweenEachAccessor.new)
|
82
124
|
end
|
83
125
|
|
126
|
+
# (see Accessory::Accessors::AllAccessor)
|
84
127
|
def all
|
85
|
-
self.then(Accessory::AllAccessor.new)
|
128
|
+
self.then(Accessory::Accessors::AllAccessor.new)
|
86
129
|
end
|
87
130
|
|
131
|
+
# (see Accessory::Accessors::FirstAccessor)
|
88
132
|
def first
|
89
|
-
self.then(Accessory::FirstAccessor.new)
|
133
|
+
self.then(Accessory::Accessors::FirstAccessor.new)
|
90
134
|
end
|
91
135
|
|
136
|
+
# (see Accessory::Accessors::LastAccessor)
|
92
137
|
def last
|
93
|
-
self.then(Accessory::LastAccessor.new)
|
138
|
+
self.then(Accessory::Accessors::LastAccessor.new)
|
94
139
|
end
|
95
140
|
|
141
|
+
# (see Accessory::Accessors::FilterAccessor)
|
96
142
|
def filter(&pred)
|
97
|
-
self.then(Accessory::FilterAccessor.new(pred))
|
143
|
+
self.then(Accessory::Accessors::FilterAccessor.new(pred))
|
98
144
|
end
|
99
145
|
end
|
100
146
|
|
@@ -102,6 +148,6 @@ class Accessory::Lens
|
|
102
148
|
include Accessory::Access::FluentHelpers
|
103
149
|
end
|
104
150
|
|
105
|
-
class Accessory::
|
151
|
+
class Accessory::BoundLens
|
106
152
|
include Accessory::Access::FluentHelpers
|
107
153
|
end
|
data/lib/accessory/accessor.rb
CHANGED
@@ -1,14 +1,36 @@
|
|
1
1
|
module Accessory; end
|
2
2
|
|
3
|
+
##
|
4
|
+
# The parent class for accessors. Contains some shared behavior all accessors
|
5
|
+
# can rely on.
|
6
|
+
#
|
7
|
+
# It doesn't make sense to instantiate this class directly. Instantiate specific
|
8
|
+
# {Accessor} subclasses instead.
|
9
|
+
#
|
10
|
+
# == Implementing an Accessor
|
11
|
+
#
|
12
|
+
# To implement an {Accessor} subclass, you must define at minimum these two
|
13
|
+
# methods (see the method docs of these methods for details):
|
14
|
+
#
|
15
|
+
# * {Accessor#get}
|
16
|
+
# * {Accessor#get_and_update}
|
17
|
+
#
|
18
|
+
# You may also implement these two methods (again, see method docs for more
|
19
|
+
# info):
|
20
|
+
#
|
21
|
+
# * {Accessor#traverse}
|
22
|
+
# * {Accessor#ensure_valid}
|
23
|
+
|
3
24
|
class Accessory::Accessor
|
4
|
-
DEFAULT_NOT_SET_SENTINEL = :"98e47971-e708-42ca-bee7-0c62fe5e11c9"
|
5
25
|
TERMINAL_DEFAULT_FN = lambda{ nil }
|
26
|
+
private_constant :TERMINAL_DEFAULT_FN
|
6
27
|
|
7
|
-
|
8
|
-
|
9
|
-
@
|
28
|
+
# @!visibility private
|
29
|
+
def initialize(default_value = nil)
|
30
|
+
@default_value = default_value
|
10
31
|
end
|
11
32
|
|
33
|
+
# @!visibility private
|
12
34
|
def name
|
13
35
|
n = self.class.name.split('::').last.gsub(/Accessor$/, '')
|
14
36
|
n.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
@@ -18,6 +40,7 @@ class Accessory::Accessor
|
|
18
40
|
n
|
19
41
|
end
|
20
42
|
|
43
|
+
# @!visibility private
|
21
44
|
def inspect(format: :long)
|
22
45
|
case format
|
23
46
|
when :long
|
@@ -30,7 +53,11 @@ class Accessory::Accessor
|
|
30
53
|
end
|
31
54
|
end
|
32
55
|
|
33
|
-
|
56
|
+
# @!visibility private
|
57
|
+
HIDDEN_IVARS = [:@default_value, :@successor]
|
58
|
+
private_constant :HIDDEN_IVARS
|
59
|
+
|
60
|
+
# @!visibility private
|
34
61
|
def inspect_args
|
35
62
|
(instance_variables - HIDDEN_IVARS).map do |ivar_k|
|
36
63
|
ivar_v = instance_variable_get(ivar_k)
|
@@ -38,18 +65,151 @@ class Accessory::Accessor
|
|
38
65
|
end.join(' ')
|
39
66
|
end
|
40
67
|
|
41
|
-
|
68
|
+
# @!visibility private
|
69
|
+
attr_accessor :successor
|
42
70
|
|
43
|
-
|
44
|
-
return nil if data.nil?
|
71
|
+
# @!group Helpers
|
45
72
|
|
46
|
-
|
47
|
-
|
73
|
+
# Safely traverses +data+, with useful defaults; simplifies implementations of
|
74
|
+
# {get} and {get_and_update}.
|
75
|
+
#
|
76
|
+
# Rather than writing redundant traversal logic into both methods, you can
|
77
|
+
# implement the callback method {traverse} to define your traversal, and then
|
78
|
+
# call <tt>traverse_or_default(data)</tt> within your implementation to safely
|
79
|
+
# get a traversal-result to operate on.
|
80
|
+
#
|
81
|
+
# The value returned by your {traverse} callback will be validated by your
|
82
|
+
# calling the {ensure_valid} callback of the _successor accessor_ in the Lens
|
83
|
+
# path. {ensure_valid} will replace any value it considers invalid with a
|
84
|
+
# reasonable default. This means you don't need to worry about what will
|
85
|
+
# happen if your traversal doesn't find a value and so returns +nil+. The
|
86
|
+
# successor's {ensure_valid} will replace that +nil+ with a value that works
|
87
|
+
# for it.
|
88
|
+
def traverse_or_default(data)
|
89
|
+
traversal_result = traverse(data) || @default_value
|
48
90
|
|
49
|
-
if
|
50
|
-
@
|
91
|
+
if @successor
|
92
|
+
@successor.ensure_valid(traversal_result)
|
51
93
|
else
|
52
|
-
|
94
|
+
traversal_result
|
53
95
|
end
|
54
96
|
end
|
97
|
+
|
98
|
+
# @!endgroup
|
99
|
+
|
100
|
+
# Traverses +data+ in some way, and feeds the result of the traversal to the
|
101
|
+
# next step in the accessor chain by yielding the traversal-result to the
|
102
|
+
# passed-in block +succ+. The result from the yield is the result coming from
|
103
|
+
# the end of the accessor chain. Usually, it should be returned as-is.
|
104
|
+
#
|
105
|
+
# +succ+ can be yielded to multiple times, to run the rest of the accessor
|
106
|
+
# chain against multiple parts of +data+. In this case, the yield results
|
107
|
+
# should be gathered up into some container object to be returned together.
|
108
|
+
#
|
109
|
+
# The successor accessor will receive the yielded element as its +data+.
|
110
|
+
#
|
111
|
+
# After returning, the predecessor accessor will receive the result returned
|
112
|
+
# from {get} as the result of its own +yield+.
|
113
|
+
#
|
114
|
+
# @param data [Enumerable] the data yielded by the predecessor accessor.
|
115
|
+
# @param succ [Proc] a thunk to the successor accessor. When {get} is called
|
116
|
+
# by a {Lens}, this is passed implicitly.
|
117
|
+
# @return [Object] the data to pass back to the predecessor accessor as a
|
118
|
+
# yield result.
|
119
|
+
def get(data, &succ)
|
120
|
+
raise NotImplementedError, "Accessor subclass #{self.class} must implement #get"
|
121
|
+
end
|
122
|
+
|
123
|
+
# Traverses +data+ in some way, and feeds the result of the traversal to the
|
124
|
+
# next step in the accessor chain by yielding the traversal-result to the
|
125
|
+
# passed-in block +succ+.
|
126
|
+
#
|
127
|
+
# The result of the yield will be a "modification command", one of these two:
|
128
|
+
# * an *update command* <tt>[get_result, new_value]</tt>
|
129
|
+
# * the symbol <tt>:pop</tt>
|
130
|
+
#
|
131
|
+
# In the *update command* case:
|
132
|
+
# * the +get_result+ should be returned as-is (or gathered together into
|
133
|
+
# a container object if this accessor yields multiple times.) The data flow
|
134
|
+
# of the +get_result+s should replicate the data flow of {get}.
|
135
|
+
# * the +new_value+ should be used to *replace* or *overwrite* the result of
|
136
|
+
# this accessor's traversal within +data+. For example, in
|
137
|
+
# {SubscriptAccessor}, <tt>data[key] = new_value</tt> is executed.
|
138
|
+
#
|
139
|
+
# In the <tt>:pop</tt> command case:
|
140
|
+
# * the result of the traversal (*before* the yield) should be returned. This
|
141
|
+
# implies that any {get_and_update} implementation must capture its
|
142
|
+
# traversal-results before feeding them into yield, in order to return them
|
143
|
+
# here.
|
144
|
+
# * the traversal-result should be *removed* from +data+. For example, in
|
145
|
+
# {SubscriptAccessor}, <tt>data.delete(key)</tt> is executed.
|
146
|
+
#
|
147
|
+
# The successor in the accessor chain will receive the yielded
|
148
|
+
# traversal-results as its own +data+.
|
149
|
+
#
|
150
|
+
# After returning, the predecessor accessor will receive the result returned
|
151
|
+
# from this method as the result of its own +yield+. This implies that
|
152
|
+
# this method should almost always be implemented to *return* an update
|
153
|
+
# command, looking like one of the following:
|
154
|
+
#
|
155
|
+
# # given [get_result, new_value]
|
156
|
+
# [get_result, data_after_update]
|
157
|
+
#
|
158
|
+
# # given :pop
|
159
|
+
# [traversal_result, data_after_removal]
|
160
|
+
#
|
161
|
+
# @param data [Enumerable] the data yielded by the predecessor accessor.
|
162
|
+
# @param succ [Proc] a thunk to the successor accessor. When {get} is called
|
163
|
+
# by a {Lens}, this is passed implicitly.
|
164
|
+
# @return [Object] the modification-command to pass back to the predecessor
|
165
|
+
# accessor as a yield result.
|
166
|
+
def get_and_update(data, &succ)
|
167
|
+
raise NotImplementedError, "Accessor subclass #{self.class} must implement #get_and_update"
|
168
|
+
end
|
169
|
+
|
170
|
+
# @!group Callbacks
|
171
|
+
|
172
|
+
# Traverses +data+; called by {traverse_or_default}.
|
173
|
+
#
|
174
|
+
# This method should traverse +data+ however your accessor does that,
|
175
|
+
# producing either one traversal-result or a container-object of gathered
|
176
|
+
# traversal-results.
|
177
|
+
#
|
178
|
+
# This method can assume that +data+ is a valid receiver for the traversal
|
179
|
+
# it performs. {traverse_or_default} takes care of feeding in a default +data+
|
180
|
+
# in the case where the predecessor passed invalid data.
|
181
|
+
#
|
182
|
+
# @param data [Object] the object to be traversed
|
183
|
+
# @return [Object] the result of traversal
|
184
|
+
def traverse(data)
|
185
|
+
raise NotImplementedError, "Accessor subclass #{self.class} must implement #traverse to use #traverse_or_default"
|
186
|
+
end
|
187
|
+
|
188
|
+
# Ensures that the predecessor accessor's traversal result is one this
|
189
|
+
# accessor can operate on; called by {traverse_or_default}.
|
190
|
+
#
|
191
|
+
# This callback should validate that the +traversal_result+ is one that can
|
192
|
+
# be traversed by the traversal-method of this accessor. If it can, the
|
193
|
+
# +traversal_result+ should be returned unchanged. If it cannot, an object
|
194
|
+
# that _can_ be traversed should be returned instead.
|
195
|
+
#
|
196
|
+
#
|
197
|
+
# For example, if your accessor operates on +Enumerable+ values (like
|
198
|
+
# {AllAccessor}), then this method should validate that the +traversal_result+
|
199
|
+
# is +Enumerable+; and, if it isn't, return something that is — e.g. an empty
|
200
|
+
# +Array+.
|
201
|
+
#
|
202
|
+
# This logic is used to replace invalid intermediate values (e.g. `nil`s and
|
203
|
+
# scalars) with containers during {Lens#put_in} et al.
|
204
|
+
#
|
205
|
+
# @return [Object] a now-valid traversal result
|
206
|
+
def ensure_valid(traversal_result)
|
207
|
+
lambda do
|
208
|
+
raise NotImplementedError, "Accessor subclass #{self.class} must implement #ensure_valid to allow chain-predecessor to use #traverse_or_default"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# @!endgroup
|
55
213
|
end
|
214
|
+
|
215
|
+
module Accessory::Accessors; end
|
@@ -1,12 +1,37 @@
|
|
1
1
|
require 'accessory/accessor'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
##
|
4
|
+
# Traverses all elements of an +Enumerable+.
|
5
|
+
#
|
6
|
+
# *Aliases*
|
7
|
+
# * {Access.all}
|
8
|
+
# * {Access::FluentHelpers#all} (included in {Lens} and {BoundLens})
|
9
|
+
#
|
10
|
+
# *Equivalents* in Elixir's {https://hexdocs.pm/elixir/Access.html +Access+} module
|
11
|
+
# * {https://hexdocs.pm/elixir/Access.html#all/0 +Access.all/0+}
|
12
|
+
# * {https://hexdocs.pm/elixir/Access.html#key/2 +Access.key/2+}
|
13
|
+
#
|
14
|
+
# <b>Default constructor</b> used by predecessor accessor
|
15
|
+
#
|
16
|
+
# * +Array.new+
|
17
|
+
|
18
|
+
class Accessory::Accessors::AllAccessor < Accessory::Accessor
|
19
|
+
# @!visibility private
|
20
|
+
def ensure_valid(traversal_result)
|
21
|
+
if traversal_result.kind_of?(Enumerable)
|
22
|
+
traversal_result
|
23
|
+
else
|
24
|
+
[]
|
25
|
+
end
|
6
26
|
end
|
7
27
|
|
28
|
+
# @!visibility private
|
8
29
|
def inspect_args; nil; end
|
9
30
|
|
31
|
+
# Feeds each element of +data+ down the accessor chain, and returns
|
32
|
+
# the results.
|
33
|
+
# @param data [Enumerable] the +Enumerable+ to iterate through
|
34
|
+
# @return [Array] the values derived from the rest of the accessor chain
|
10
35
|
def get(data, &succ)
|
11
36
|
if succ
|
12
37
|
(data || []).map(&succ)
|
@@ -15,6 +40,13 @@ class Accessory::AllAccessor < Accessory::Accessor
|
|
15
40
|
end
|
16
41
|
end
|
17
42
|
|
43
|
+
# Feeds each element of +data+ down the accessor chain, overwriting
|
44
|
+
# +data+ with the results.
|
45
|
+
#
|
46
|
+
# If +:pop+ is returned from the accessor chain, the element is dropped
|
47
|
+
# from the new +data+.
|
48
|
+
# @param data [Enumerable] the +Enumerable+ to iterate through
|
49
|
+
# @return [Array] a two-element array containing 1. the original values found during iteration; and 2. the new +data+
|
18
50
|
def get_and_update(data)
|
19
51
|
results = []
|
20
52
|
new_data = []
|