accessory 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 43e0f691627cd491ac44fecb56547a50a5688215a1a65a494407557b9e6abc0b
4
+ data.tar.gz: 6775e183ab5791f8fb7e484593bc9cda59fde745a7f7bbfd38fd7fd3180a5c77
5
+ SHA512:
6
+ metadata.gz: 9a258b50f71e28a4f43c934aa53fdb53e348665ae2c269a0f427fbc6febdda97a00e6891d12c5d9cb53a94be513a0c4e59d1739d6d11656aabf1898364738bcc
7
+ data.tar.gz: 7bfb51fa829b919ac35a78e0ee17aa9f2edd439e155df61c509dada8a94c8ed0f5c2d3915b1766869547b558685175d8691a3c7ccaffe32b5becd9d00445d2d1
@@ -0,0 +1,14 @@
1
+ module Accessory; end
2
+
3
+ require 'accessory/version'
4
+ require 'accessory/lens_path'
5
+ require 'accessory/lens'
6
+ require 'accessory/access'
7
+
8
+ module Accessory
9
+ refine ::Object do
10
+ def lens
11
+ ::Accessory::Lens.on(self)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,107 @@
1
+ module Accessory; end
2
+
3
+ require 'accessory/accessors/subscript_accessor'
4
+ require 'accessory/accessors/field_accessor'
5
+ require 'accessory/accessors/filter_accessor'
6
+ require 'accessory/accessors/instance_variable_accessor'
7
+ require 'accessory/accessors/betwixt_accessor'
8
+ require 'accessory/accessors/between_each_accessor'
9
+ require 'accessory/accessors/all_accessor'
10
+ require 'accessory/accessors/first_accessor'
11
+ require 'accessory/accessors/last_accessor'
12
+
13
+ module Accessory::Access
14
+ def self.field(...)
15
+ Accessory::FieldAccessor.new(...)
16
+ end
17
+
18
+ def self.ivar(...)
19
+ Accessory::InstanceVariableAccessor.new(...)
20
+ end
21
+
22
+ def self.betwixt(...)
23
+ Accessory::BetwixtAccessor.new(...)
24
+ end
25
+
26
+ def self.before_first
27
+ self.betwixt(0)
28
+ end
29
+
30
+ def self.after_last
31
+ self.betwixt(-1)
32
+ end
33
+
34
+ def self.between_each
35
+ Accessory::BetweenEachAccessor.new
36
+ end
37
+
38
+ def self.all
39
+ Accessory::AllAccessor.new
40
+ end
41
+
42
+ def self.first
43
+ Accessory::FirstAccessor.new
44
+ end
45
+
46
+ def self.last
47
+ Accessory::LastAccessor.new
48
+ end
49
+
50
+ def self.filter(&pred)
51
+ Accessory::FilterAccessor.new(pred)
52
+ end
53
+ end
54
+
55
+ module Accessory::Access::FluentHelpers
56
+ def [](...)
57
+ self.then(Accessory::SubscriptAccessor.new(...))
58
+ end
59
+
60
+ def field(...)
61
+ self.then(Accessory::FieldAccessor.new(...))
62
+ end
63
+
64
+ def ivar(...)
65
+ self.then(Accessory::InstanceVariableAccessor.new(...))
66
+ end
67
+
68
+ def betwixt(...)
69
+ self.then(Accessory::BetwixtAccessor.new(...))
70
+ end
71
+
72
+ def before_first
73
+ self.betwixt(0)
74
+ end
75
+
76
+ def after_last
77
+ self.betwixt(-1)
78
+ end
79
+
80
+ def between_each
81
+ self.then(Accessory::BetweenEachAccessor.new)
82
+ end
83
+
84
+ def all
85
+ self.then(Accessory::AllAccessor.new)
86
+ end
87
+
88
+ def first
89
+ self.then(Accessory::FirstAccessor.new)
90
+ end
91
+
92
+ def last
93
+ self.then(Accessory::LastAccessor.new)
94
+ end
95
+
96
+ def filter(&pred)
97
+ self.then(Accessory::FilterAccessor.new(pred))
98
+ end
99
+ end
100
+
101
+ class Accessory::Lens
102
+ include Accessory::Access::FluentHelpers
103
+ end
104
+
105
+ class Accessory::LensPath
106
+ include Accessory::Access::FluentHelpers
107
+ end
@@ -0,0 +1,55 @@
1
+ module Accessory; end
2
+
3
+ class Accessory::Accessor
4
+ DEFAULT_NOT_SET_SENTINEL = :"98e47971-e708-42ca-bee7-0c62fe5e11c9"
5
+ TERMINAL_DEFAULT_FN = lambda{ nil }
6
+
7
+ def initialize(default: DEFAULT_NOT_SET_SENTINEL)
8
+ @default_value = default
9
+ @make_default_fn = TERMINAL_DEFAULT_FN
10
+ end
11
+
12
+ def name
13
+ n = self.class.name.split('::').last.gsub(/Accessor$/, '')
14
+ n.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
15
+ n.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
16
+ n.tr!("-", "_")
17
+ n.downcase!
18
+ n
19
+ end
20
+
21
+ def inspect(format: :long)
22
+ case format
23
+ when :long
24
+ parts = ["Access.#{self.name}", inspect_args].compact.join(' ')
25
+ "#<#{parts}>"
26
+ when :short
27
+ fn_name = "Access.#{self.name}"
28
+ args = inspect_args
29
+ args ? "#{fn_name}(#{args})" : fn_name
30
+ end
31
+ end
32
+
33
+ HIDDEN_IVARS = [:@default_value, :@make_default_fn]
34
+ def inspect_args
35
+ (instance_variables - HIDDEN_IVARS).map do |ivar_k|
36
+ ivar_v = instance_variable_get(ivar_k)
37
+ "#{ivar_k}=#{ivar_v.inspect}"
38
+ end.join(' ')
39
+ end
40
+
41
+ attr_accessor :make_default_fn
42
+
43
+ def value_or_default(data)
44
+ return nil if data.nil?
45
+
46
+ maybe_value = value_from(data)
47
+ return maybe_value unless maybe_value.nil?
48
+
49
+ if DEFAULT_NOT_SET_SENTINEL.equal?(@default_value)
50
+ @make_default_fn.call
51
+ else
52
+ @default_value
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::AllAccessor < Accessory::Accessor
4
+ def default_fn_for_previous_step
5
+ lambda{ Array.new }
6
+ end
7
+
8
+ def inspect_args; nil; end
9
+
10
+ def get(data, &succ)
11
+ if succ
12
+ (data || []).map(&succ)
13
+ else
14
+ data
15
+ end
16
+ end
17
+
18
+ def get_and_update(data)
19
+ results = []
20
+ new_data = []
21
+
22
+ (data || []).each do |pos|
23
+ case yield(pos)
24
+ in [result, new_value]
25
+ results.push(result)
26
+ new_data.push(new_value)
27
+ in :pop
28
+ results.push(pos)
29
+ end
30
+ end
31
+
32
+ [results, new_data]
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ require 'accessory/accessor'
2
+ require 'accessory/array_cursor_position'
3
+
4
+ class Accessory::BetweenEachAccessor < Accessory::Accessor
5
+ def default_fn_for_previous_step
6
+ lambda{ Array.new }
7
+ end
8
+
9
+ def inspect_args; nil; end
10
+
11
+ def value_from(data)
12
+ data_len = data.length
13
+
14
+ positions = [
15
+ (0..data_len).to_a,
16
+ data + [nil],
17
+ [nil] + data
18
+ ]
19
+
20
+ positions.transpose.map do |(i, b, a)|
21
+ Accessory::ArrayCursorPosition.new(i, b, a, is_first: i == 0, is_last: i == data_len)
22
+ end
23
+ end
24
+
25
+ def get(data)
26
+ positions = value_or_default(data || [])
27
+
28
+ if block_given?
29
+ positions.map{ |rec| yield(rec) }
30
+ else
31
+ positions
32
+ end
33
+ end
34
+
35
+ def get_and_update(data)
36
+ results = []
37
+ new_data = []
38
+
39
+ positions = value_or_default(data || [])
40
+
41
+ positions.each do |pos|
42
+ case yield(pos)
43
+ in [result, new_value]
44
+ new_data.push(new_value)
45
+ results.push(result)
46
+ in :pop
47
+ end
48
+
49
+ unless pos.last?
50
+ new_data.push(pos.elem_after)
51
+ end
52
+ end
53
+
54
+ [results, new_data]
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ require 'accessory/accessor'
2
+ require 'accessory/array_cursor_position'
3
+
4
+ class Accessory::BetwixtAccessor < Accessory::Accessor
5
+ def initialize(offset, **kwargs)
6
+ super(**kwargs)
7
+ @offset = offset
8
+ end
9
+
10
+ def inspect_args
11
+ @offset.inspect
12
+ end
13
+
14
+ def default_fn_for_previous_step
15
+ lambda{ Array.new }
16
+ end
17
+
18
+ def value_from(data)
19
+ data_len = data.length
20
+
21
+ Accessory::ArrayCursorPosition.new(
22
+ @offset,
23
+ (@offset > 0) ? data[@offset - 1] : nil,
24
+ (@offset < (data_len - 1)) ? data[@offset + 1] : nil,
25
+ is_first: @offset == 0,
26
+ is_last: @offset == data_len
27
+ )
28
+ end
29
+
30
+ def get(data)
31
+ pos = value_or_default(data || [])
32
+
33
+ if block_given?
34
+ yield(pos)
35
+ else
36
+ pos
37
+ end
38
+ end
39
+
40
+ def get_and_update(data)
41
+ pos = value_or_default(data || [])
42
+
43
+ case yield(pos)
44
+ in [result, new_value]
45
+ data ||= []
46
+ data.insert(@offset, new_value)
47
+ [result, data]
48
+ in :pop
49
+ [nil, data]
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,47 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::FieldAccessor < Accessory::Accessor
4
+ def initialize(field_name, **kwargs)
5
+ super(**kwargs)
6
+ @getter_method_name = :"#{field_name}"
7
+ @setter_method_name = :"#{field_name}="
8
+ end
9
+
10
+ def inspect_args
11
+ @getter_method_name.inspect
12
+ end
13
+
14
+ def default_fn_for_previous_step
15
+ lambda do
16
+ require 'ostruct'
17
+ OpenStruct.new
18
+ end
19
+ end
20
+
21
+ def value_from(data)
22
+ data.send(@getter_method_name)
23
+ end
24
+
25
+ def get(data)
26
+ value = value_or_default(data)
27
+
28
+ if block_given?
29
+ yield(value)
30
+ else
31
+ value
32
+ end
33
+ end
34
+
35
+ def get_and_update(data)
36
+ value = value_or_default(data)
37
+
38
+ case yield(value)
39
+ in [result, new_value]
40
+ data.send(@setter_method_name, new_value)
41
+ [result, data]
42
+ in :pop
43
+ data.send(@setter_method_name, nil)
44
+ [value, data]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::FilterAccessor < Accessory::Accessor
4
+ def initialize(pred)
5
+ @pred = pred
6
+ end
7
+
8
+ def inspect_args
9
+ @pred.inspect
10
+ end
11
+
12
+ def default_fn_for_previous_step
13
+ lambda{ Array.new }
14
+ end
15
+
16
+ def get(data, &succ)
17
+ if succ
18
+ (data || []).filter(&@pred).map(&succ)
19
+ else
20
+ data
21
+ end
22
+ end
23
+
24
+ def get_and_update(data)
25
+ results = []
26
+ new_data = []
27
+
28
+ (data || []).each do |pos|
29
+ unless @pred.call(pos)
30
+ new_data.push(pos)
31
+ next
32
+ end
33
+
34
+ case yield(pos)
35
+ in [result, new_value]
36
+ results.push(result)
37
+ new_data.push(new_value)
38
+ in :pop
39
+ results.push(pos)
40
+ end
41
+ end
42
+
43
+ [results, new_data]
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::FirstAccessor < Accessory::Accessor
4
+ def default_fn_for_previous_step
5
+ lambda{ Array.new }
6
+ end
7
+
8
+ def inspect_args; nil; end
9
+
10
+ def value_from(data)
11
+ data.first
12
+ end
13
+
14
+ def get(data)
15
+ value = value_or_default(data)
16
+
17
+ if block_given?
18
+ yield(value)
19
+ else
20
+ value
21
+ end
22
+ end
23
+
24
+ def get_and_update(data)
25
+ old_value = value_or_default(data)
26
+
27
+ case yield(old_value)
28
+ in [result, new_value]
29
+ data[0] = new_value
30
+ [result, data]
31
+ in :pop
32
+ data.delete_at(0)
33
+ [old_value, data]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,48 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::InstanceVariableAccessor < Accessory::Accessor
4
+ def initialize(ivar_name, **kwargs)
5
+ super(**kwargs)
6
+
7
+ ivar_name = ivar_name.to_s
8
+ ivar_name = "@#{ivar_name}" unless ivar_name.to_s.start_with?("@")
9
+ ivar_name = ivar_name.intern
10
+
11
+ @ivar_name = ivar_name
12
+ end
13
+
14
+ def inspect_args
15
+ @ivar_name.to_s
16
+ end
17
+
18
+ def default_fn_for_previous_step
19
+ lambda{ Object.new }
20
+ end
21
+
22
+ def value_from(data)
23
+ data.instance_variable_get(@ivar_name)
24
+ end
25
+
26
+ def get(data)
27
+ value = value_or_default(data)
28
+
29
+ if block_given?
30
+ yield(value)
31
+ else
32
+ value
33
+ end
34
+ end
35
+
36
+ def get_and_update(data)
37
+ value = value_or_default(data)
38
+
39
+ case yield(value)
40
+ in [result, new_value]
41
+ data.instance_variable_set(@ivar_name, new_value)
42
+ [result, data]
43
+ in :pop
44
+ data.remove_instance_variable(@ivar_name)
45
+ [value, data]
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,36 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::LastAccessor < Accessory::Accessor
4
+ def default_fn_for_previous_step
5
+ lambda{ Array.new }
6
+ end
7
+
8
+ def inspect_args; nil; end
9
+
10
+ def value_from(data)
11
+ data.last
12
+ end
13
+
14
+ def get(data)
15
+ value = value_or_default(data)
16
+
17
+ if block_given?
18
+ yield(value)
19
+ else
20
+ value
21
+ end
22
+ end
23
+
24
+ def get_and_update(data)
25
+ old_value = value_or_default(data)
26
+
27
+ case yield(old_value)
28
+ in [result, new_value]
29
+ data[-1] = new_value
30
+ [result, data]
31
+ in :pop
32
+ data.delete_at(-1)
33
+ [old_value, data]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ require 'accessory/accessor'
2
+
3
+ class Accessory::SubscriptAccessor < Accessory::Accessor
4
+ def initialize(key, **kwargs)
5
+ super(**kwargs)
6
+ @key = key
7
+ end
8
+
9
+ def inspect(format: :long)
10
+ case format
11
+ when :long
12
+ super()
13
+ when :short
14
+ @key.inspect
15
+ end
16
+ end
17
+
18
+ def inspect_args
19
+ @key.inspect
20
+ end
21
+
22
+ def default_fn_for_previous_step
23
+ lambda{ Hash.new }
24
+ end
25
+
26
+ def value_from(data)
27
+ data[@key]
28
+ end
29
+
30
+ def get(data)
31
+ value = value_or_default(data)
32
+
33
+ if block_given?
34
+ yield(value)
35
+ else
36
+ value
37
+ end
38
+ end
39
+
40
+ def get_and_update(data)
41
+ value = value_or_default(data)
42
+
43
+ case yield(value)
44
+ in [result, new_value]
45
+ data[@key] = new_value
46
+ [result, data]
47
+ in :pop
48
+ data.delete(@key)
49
+ [value, data]
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ module Accessory; end
2
+
3
+ class Accessory::ArrayCursorPosition
4
+ def initialize(offset, elem_before, elem_after, is_first: false, is_last: false)
5
+ @offset = offset
6
+ @elem_before = elem_before
7
+ @elem_after = elem_after
8
+ @is_first = is_first
9
+ @is_last = is_last
10
+ end
11
+
12
+ attr_reader :offset
13
+ attr_reader :elem_before
14
+ attr_reader :elem_after
15
+
16
+ def first?; @is_first; end
17
+ def last?; @is_last; end
18
+ end
@@ -0,0 +1,66 @@
1
+ module Accessory; end
2
+
3
+ require 'accessory/lens_path'
4
+
5
+ class Accessory::Lens
6
+ def self.on(doc, path: nil)
7
+ self.new(doc, path || Accessory::LensPath.empty).freeze
8
+ end
9
+
10
+ class << self
11
+ private :new
12
+ end
13
+
14
+ def initialize(doc, lens_path)
15
+ @doc = doc
16
+ @path = lens_path
17
+ end
18
+
19
+ attr_reader :path
20
+
21
+ def inspect
22
+ "#<Lens on=#{@doc.inspect} #{@path.inspect(format: :short)}>"
23
+ end
24
+
25
+ def then(accessor)
26
+ d = self.dup
27
+ d.instance_eval do
28
+ @path = @path.then(accessor)
29
+ end
30
+ d.freeze
31
+ end
32
+
33
+ def +(lens_path)
34
+ d = self.dup
35
+ d.instance_eval do
36
+ @path = @path + lens_path
37
+ end
38
+ d.freeze
39
+ end
40
+
41
+ def get_in
42
+ @path.get_in(@doc)
43
+ end
44
+
45
+ def get_and_update_in(&mutator_fn)
46
+ @path.get_and_update_in(@doc, &mutator_fn)
47
+ end
48
+
49
+ def update_in(&new_value_fn)
50
+ @path.update_in(@doc, &new_value_fn)
51
+ end
52
+
53
+ def put_in(new_value)
54
+ @path.put_in(@doc, new_value)
55
+ end
56
+
57
+ def pop_in
58
+ @path.pop_in(@doc)
59
+ end
60
+ end
61
+
62
+ class Accessory::LensPath
63
+ def on(doc)
64
+ Accessory::Lens.on(doc, path: self)
65
+ end
66
+ end
@@ -0,0 +1,140 @@
1
+ module Accessory; end
2
+
3
+ require 'accessory/accessor'
4
+ require 'accessory/accessors/subscript_accessor'
5
+
6
+ class Accessory::LensPath
7
+ def self.empty
8
+ @empty_lens_path ||= (new([]).freeze)
9
+ end
10
+
11
+ def self.[](*path)
12
+ new(path).freeze
13
+ end
14
+
15
+ class << self
16
+ private :new
17
+ end
18
+
19
+ def initialize(initial_parts)
20
+ @parts = []
21
+
22
+ for part in initial_parts
23
+ append_accessor!(part)
24
+ end
25
+ end
26
+
27
+ def to_a
28
+ @parts
29
+ end
30
+
31
+ def inspect(format: :long)
32
+ parts_desc = @parts.map{ |part| part.inspect(format: :short) }.join(', ')
33
+ parts_desc = "[#{parts_desc}]"
34
+
35
+ case format
36
+ when :long
37
+ "#LensPath#{parts_desc}"
38
+ when :short
39
+ parts_desc
40
+ end
41
+ end
42
+
43
+ def then(accessor)
44
+ d = self.dup
45
+ d.append_accessor!(accessor)
46
+ d.freeze
47
+ end
48
+
49
+ def dup
50
+ d = super
51
+ d.instance_eval do
52
+ @parts = @parts.dup
53
+ end
54
+ d
55
+ end
56
+
57
+ def +(lp_b)
58
+ raise ArgumentError unless lp_b.kind_of?(Accessory::LensPath)
59
+
60
+ d = self.dup
61
+ for part in lp_b.to_a
62
+ d.append_accessor!(part)
63
+ end
64
+ d.freeze
65
+ end
66
+
67
+ def append_accessor!(part)
68
+ accessor =
69
+ case part
70
+ when Accessory::Accessor
71
+ part
72
+ when Array
73
+ Accessory::SubscriptAccessor.new(part[0], default: part[1])
74
+ else
75
+ Accessory::SubscriptAccessor.new(part)
76
+ end
77
+
78
+ unless @parts.empty?
79
+ @parts.last.make_default_fn = accessor.default_fn_for_previous_step
80
+ end
81
+
82
+ @parts.push(accessor)
83
+ end
84
+
85
+ protected :append_accessor!
86
+
87
+ def get_in(doc)
88
+ if @parts.empty?
89
+ doc
90
+ else
91
+ get_in_step(doc, @parts)
92
+ end
93
+ end
94
+
95
+ def get_and_update_in(doc, &mutator_fn)
96
+ if @parts.empty?
97
+ doc
98
+ else
99
+ get_and_update_in_step(doc, @parts, mutator_fn)
100
+ end
101
+ end
102
+
103
+ def update_in(data, &new_value_fn)
104
+ _, new_data = self.get_and_update_in(data){ |v| [nil, new_value_fn.call(v)] }
105
+ new_data
106
+ end
107
+
108
+ def put_in(data, new_value)
109
+ _, new_data = self.get_and_update_in(data){ [nil, new_value] }
110
+ new_data
111
+ end
112
+
113
+ def pop_in(data)
114
+ self.get_and_update_in(data){ :pop }
115
+ end
116
+
117
+ private
118
+ def get_in_step(data, path)
119
+ step_accessor = path.first
120
+ rest_of_path = path[1..-1]
121
+
122
+ if rest_of_path.empty?
123
+ step_accessor.get(data)
124
+ else
125
+ step_accessor.get(data){ |v| get_in_step(v, rest_of_path) }
126
+ end
127
+ end
128
+
129
+ private
130
+ def get_and_update_in_step(data, path, mutator_fn)
131
+ step_accessor = path.first
132
+ rest_of_path = path[1..-1]
133
+
134
+ if rest_of_path.empty?
135
+ step_accessor.get_and_update(data, &mutator_fn)
136
+ else
137
+ step_accessor.get_and_update(data){ |v| get_and_update_in_step(v, rest_of_path, mutator_fn) }
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,3 @@
1
+ module Accessory
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: accessory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Levi Aul
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - levi@leviaul.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/accessory.rb
21
+ - lib/accessory/access.rb
22
+ - lib/accessory/accessor.rb
23
+ - lib/accessory/accessors/all_accessor.rb
24
+ - lib/accessory/accessors/between_each_accessor.rb
25
+ - lib/accessory/accessors/betwixt_accessor.rb
26
+ - lib/accessory/accessors/field_accessor.rb
27
+ - lib/accessory/accessors/filter_accessor.rb
28
+ - lib/accessory/accessors/first_accessor.rb
29
+ - lib/accessory/accessors/instance_variable_accessor.rb
30
+ - lib/accessory/accessors/last_accessor.rb
31
+ - lib/accessory/accessors/subscript_accessor.rb
32
+ - lib/accessory/array_cursor_position.rb
33
+ - lib/accessory/lens.rb
34
+ - lib/accessory/lens_path.rb
35
+ - lib/accessory/version.rb
36
+ homepage: https://github.com/tsutsu/accessory
37
+ licenses:
38
+ - MIT
39
+ metadata:
40
+ homepage_uri: https://github.com/tsutsu/accessory
41
+ source_code_uri: https://github.com/tsutsu/accessory
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 2.7.0
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubygems_version: 3.2.3
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: Functional lenses for Ruby, borrowed from Elixir
61
+ test_files: []