callable_tree 0.3.3 → 0.3.6
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/.github/workflows/build.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +3 -4
- data/README.md +47 -47
- data/examples/builder/hooks-caller.rb +38 -0
- data/examples/builder/internal-broadcastable.rb +72 -0
- data/examples/builder/internal-composable.rb +72 -0
- data/examples/builder/internal-seekable.rb +93 -0
- data/examples/builder/logging.rb +126 -0
- data/examples/{hooks-call.rb → hooks-caller.rb} +8 -8
- data/examples/{internal-broadcast.rb → internal-broadcastable.rb} +6 -6
- data/examples/{internal-compose.rb → internal-composable.rb} +6 -6
- data/examples/{internal-seek.rb → internal-seekable.rb} +3 -3
- data/lib/callable_tree/node/builder.rb +85 -0
- data/lib/callable_tree/node/external/builder.rb +23 -0
- data/lib/callable_tree/node/external/verbose.rb +0 -1
- data/lib/callable_tree/node/hooks/caller.rb +110 -0
- data/lib/callable_tree/node/hooks/matcher.rb +101 -0
- data/lib/callable_tree/node/internal/builder.rb +21 -0
- data/lib/callable_tree/node/internal.rb +12 -0
- data/lib/callable_tree/node/root.rb +2 -1
- data/lib/callable_tree/version.rb +1 -1
- data/lib/callable_tree.rb +5 -1
- metadata +18 -9
- data/lib/callable_tree/node/hooks/call.rb +0 -81
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a83d353d4049c06aa0a0d5f18f56c5c6d0d909cd4a54f6bbcba7faf4e835c0f
|
4
|
+
data.tar.gz: ab803f4e8b613a0ceb5e4d3ca21d38e1a5cf2a238db61384c0ec85b437fd7d73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27dd59b36d4ebc99395df901a900d72510928f5f4a9603405b83f54d0566652fda2253bcda7bf6efee1ad0363919c5ec7bb63a1ec1e0efc488e656d6ff1bce3a
|
7
|
+
data.tar.gz: 3029f92901053688715cffce367d0e44f01402743413dfd38dc52c6c63221094fe2d3774cf2b1b98d66b84dd6837c8d6e6430c228ce3f196e60f9222286a3a56
|
data/.github/workflows/build.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.6] - 2022-03-29
|
4
|
+
|
5
|
+
- (Experimental) Add `CallableTree::Node::Hooks::Matcher`.
|
6
|
+
Using this together with `CallableTree::Node::Hooks::Caller` helps to output logs. See `examples/builder/logging.rb` for details.
|
7
|
+
|
8
|
+
## [0.3.5] - 2022-03-20
|
9
|
+
|
10
|
+
- Add `CallableTree::Node::Internal#seekable?` as an alias for `CallableTree::Node::Internal#seek?`.
|
11
|
+
- Add `CallableTree::Node::Internal#seekable` as an alias for `CallableTree::Node::Internal#seek`.
|
12
|
+
- Add `CallableTree::Node::Internal#seekable!` as an alias for `CallableTree::Node::Internal#seek!`.
|
13
|
+
- Add `CallableTree::Node::Internal#broadcastable?` as an alias for `CallableTree::Node::Internal#broadcast?`.
|
14
|
+
- Add `CallableTree::Node::Internal#broadcastable` as an alias for `CallableTree::Node::Internal#broadcast`.
|
15
|
+
- Add `CallableTree::Node::Internal#broadcastable!` as an alias for `CallableTree::Node::Internal#broadcast!`.
|
16
|
+
- Add `CallableTree::Node::Internal#composable?` as an alias for `CallableTree::Node::Internal#compose?`.
|
17
|
+
- Add `CallableTree::Node::Internal#composable` as an alias for `CallableTree::Node::Internal#compose`.
|
18
|
+
- Add `CallableTree::Node::Internal#composable!` as an alias for `CallableTree::Node::Internal#compose!`.
|
19
|
+
- (Experimental) Add `CallableTree::Node::Internal::Builder#terminator` to use instead of `CallableTree::Node::Internal::Builder#terminater`.
|
20
|
+
See `examples/builder/*.rb` for details.
|
21
|
+
|
22
|
+
## [0.3.4] - 2022-03-13
|
23
|
+
|
24
|
+
- (Experimental) Add `CallableTree::Node::Internal::Builder`.
|
25
|
+
See `examples/builder/*.rb` for details.
|
26
|
+
- (Experimental) Add `CallableTree::Node::External::Builder`.
|
27
|
+
See `examples/builder/*.rb` for details.
|
28
|
+
|
3
29
|
## [0.3.3] - 2022-02-19
|
4
30
|
|
5
31
|
- Add `recursive` option to `CallableTree::Node::Internal#reject` and `CallableTree::Node::Internal#reject!`.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
callable_tree (0.3.
|
4
|
+
callable_tree (0.3.6)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -23,8 +23,7 @@ GEM
|
|
23
23
|
rspec-support (3.11.0)
|
24
24
|
|
25
25
|
PLATFORMS
|
26
|
-
x86_64-darwin-
|
27
|
-
x86_64-darwin-20
|
26
|
+
x86_64-darwin-21
|
28
27
|
|
29
28
|
DEPENDENCIES
|
30
29
|
callable_tree!
|
@@ -32,4 +31,4 @@ DEPENDENCIES
|
|
32
31
|
rspec (~> 3.0)
|
33
32
|
|
34
33
|
BUNDLED WITH
|
35
|
-
2.3.
|
34
|
+
2.3.7
|
data/README.md
CHANGED
@@ -32,11 +32,11 @@ Builds a tree by linking instances of the nodes. The `call` method of the node w
|
|
32
32
|
|
33
33
|
### Basic
|
34
34
|
|
35
|
-
#### `CallableTree::Node::Internal#
|
35
|
+
#### `CallableTree::Node::Internal#seekable` (default)
|
36
36
|
|
37
37
|
This strategy does not call the next sibling node if the `call` method of the current node returns a value other than `nil`. This behavior is changeable by overriding the `terminate?` method.
|
38
38
|
|
39
|
-
`examples/internal-
|
39
|
+
`examples/internal-seekable.rb`:
|
40
40
|
```ruby
|
41
41
|
module Node
|
42
42
|
module JSON
|
@@ -129,17 +129,17 @@ module Node
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
# The `
|
133
|
-
tree = CallableTree::Node::Root.new.append(
|
134
|
-
Node::JSON::Parser.new.append(
|
132
|
+
# The `seekable` method call can be omitted since it is the default strategy.
|
133
|
+
tree = CallableTree::Node::Root.new.seekable.append(
|
134
|
+
Node::JSON::Parser.new.seekable.append(
|
135
135
|
Node::JSON::Scraper.new(type: :animals),
|
136
136
|
Node::JSON::Scraper.new(type: :fruits)
|
137
|
-
)
|
138
|
-
Node::XML::Parser.new.append(
|
137
|
+
),
|
138
|
+
Node::XML::Parser.new.seekable.append(
|
139
139
|
Node::XML::Scraper.new(type: :animals),
|
140
140
|
Node::XML::Scraper.new(type: :fruits)
|
141
|
-
)
|
142
|
-
)
|
141
|
+
)
|
142
|
+
)
|
143
143
|
|
144
144
|
Dir.glob("#{__dir__}/docs/*") do |file|
|
145
145
|
options = { foo: :bar }
|
@@ -148,9 +148,9 @@ Dir.glob("#{__dir__}/docs/*") do |file|
|
|
148
148
|
end
|
149
149
|
```
|
150
150
|
|
151
|
-
Run `examples/internal-
|
151
|
+
Run `examples/internal-seekable.rb`:
|
152
152
|
```sh
|
153
|
-
% ruby examples/internal-
|
153
|
+
% ruby examples/internal-seekable.rb
|
154
154
|
{"Dog"=>"🐶", "Cat"=>"🐱"}
|
155
155
|
---
|
156
156
|
{"Dog"=>"🐶", "Cat"=>"🐱"}
|
@@ -161,11 +161,11 @@ Run `examples/internal-seek.rb`:
|
|
161
161
|
---
|
162
162
|
```
|
163
163
|
|
164
|
-
#### `CallableTree::Node::Internal#
|
164
|
+
#### `CallableTree::Node::Internal#broadcastable`
|
165
165
|
|
166
166
|
This strategy calls all child nodes of the internal node and ignores their `terminate?` methods, and then outputs their results as array.
|
167
167
|
|
168
|
-
`examples/internal-
|
168
|
+
`examples/internal-broadcastable.rb`:
|
169
169
|
```ruby
|
170
170
|
module Node
|
171
171
|
class LessThan
|
@@ -181,16 +181,16 @@ module Node
|
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
|
-
tree = CallableTree::Node::Root.new.append(
|
185
|
-
Node::LessThan.new(5).append(
|
184
|
+
tree = CallableTree::Node::Root.new.broadcastable.append(
|
185
|
+
Node::LessThan.new(5).broadcastable.append(
|
186
186
|
->(input) { input * 2 }, # anonymous external node
|
187
187
|
->(input) { input + 1 } # anonymous external node
|
188
|
-
)
|
189
|
-
Node::LessThan.new(10).append(
|
188
|
+
),
|
189
|
+
Node::LessThan.new(10).broadcastable.append(
|
190
190
|
->(input) { input * 3 }, # anonymous external node
|
191
191
|
->(input) { input - 1 } # anonymous external node
|
192
|
-
)
|
193
|
-
)
|
192
|
+
)
|
193
|
+
)
|
194
194
|
|
195
195
|
(0..10).each do |input|
|
196
196
|
output = tree.call(input)
|
@@ -199,9 +199,9 @@ end
|
|
199
199
|
|
200
200
|
```
|
201
201
|
|
202
|
-
Run `examples/internal-
|
202
|
+
Run `examples/internal-broadcastable.rb`:
|
203
203
|
```sh
|
204
|
-
% ruby examples/internal-
|
204
|
+
% ruby examples/internal-broadcastable.rb
|
205
205
|
0 -> [[0, 1], [0, -1]]
|
206
206
|
1 -> [[2, 2], [3, 0]]
|
207
207
|
2 -> [[4, 3], [6, 1]]
|
@@ -215,11 +215,11 @@ Run `examples/internal-broadcast.rb`:
|
|
215
215
|
10 -> [nil, nil]
|
216
216
|
```
|
217
217
|
|
218
|
-
#### `CallableTree::Node::Internal#
|
218
|
+
#### `CallableTree::Node::Internal#composable`
|
219
219
|
|
220
220
|
This strategy calls all child nodes of the internal node in order to input the output of the previous node to the next node and ignores their `terminate?` methods, and then outputs a single result.
|
221
221
|
|
222
|
-
`examples/internal-
|
222
|
+
`examples/internal-composable.rb`:
|
223
223
|
```ruby
|
224
224
|
module Node
|
225
225
|
class LessThan
|
@@ -235,16 +235,16 @@ module Node
|
|
235
235
|
end
|
236
236
|
end
|
237
237
|
|
238
|
-
tree = CallableTree::Node::Root.new.append(
|
239
|
-
Node::LessThan.new(5).append(
|
238
|
+
tree = CallableTree::Node::Root.new.composable.append(
|
239
|
+
Node::LessThan.new(5).composable.append(
|
240
240
|
proc { |input| input * 2 }, # anonymous external node
|
241
241
|
proc { |input| input + 1 } # anonymous external node
|
242
|
-
)
|
243
|
-
Node::LessThan.new(10).append(
|
242
|
+
),
|
243
|
+
Node::LessThan.new(10).composable.append(
|
244
244
|
proc { |input| input * 3 }, # anonymous external node
|
245
245
|
proc { |input| input - 1 } # anonymous external node
|
246
|
-
)
|
247
|
-
)
|
246
|
+
)
|
247
|
+
)
|
248
248
|
|
249
249
|
(0..10).each do |input|
|
250
250
|
output = tree.call(input)
|
@@ -253,9 +253,9 @@ end
|
|
253
253
|
|
254
254
|
```
|
255
255
|
|
256
|
-
Run `examples/internal-
|
256
|
+
Run `examples/internal-composable.rb`:
|
257
257
|
```sh
|
258
|
-
% ruby examples/internal-
|
258
|
+
% ruby examples/internal-composable.rb
|
259
259
|
0 -> 2
|
260
260
|
1 -> 8
|
261
261
|
2 -> 14
|
@@ -568,20 +568,20 @@ Run `examples/logging.rb`:
|
|
568
568
|
---
|
569
569
|
```
|
570
570
|
|
571
|
-
#### `CallableTree::Node::Hooks::
|
571
|
+
#### `CallableTree::Node::Hooks::Caller` (experimental)
|
572
572
|
|
573
573
|
`examples/hooks-call.rb`:
|
574
574
|
```ruby
|
575
575
|
module Node
|
576
576
|
class HooksSample
|
577
577
|
include CallableTree::Node::Internal
|
578
|
-
prepend CallableTree::Node::Hooks::
|
578
|
+
prepend CallableTree::Node::Hooks::Caller
|
579
579
|
end
|
580
580
|
end
|
581
581
|
|
582
582
|
Node::HooksSample.new
|
583
|
-
.
|
584
|
-
puts "
|
583
|
+
.before_caller do |input, **_options|
|
584
|
+
puts "before_caller input: #{input}";
|
585
585
|
input + 1
|
586
586
|
end
|
587
587
|
.append(
|
@@ -591,14 +591,14 @@ Node::HooksSample.new
|
|
591
591
|
input * 2
|
592
592
|
end
|
593
593
|
)
|
594
|
-
.
|
595
|
-
puts "
|
594
|
+
.around_caller do |input, **_options, &block|
|
595
|
+
puts "around_caller input: #{input}"
|
596
596
|
output = block.call
|
597
|
-
puts "
|
597
|
+
puts "around_caller output: #{output}"
|
598
598
|
output * input
|
599
599
|
end
|
600
|
-
.
|
601
|
-
puts "
|
600
|
+
.after_caller do |output, **_options|
|
601
|
+
puts "after_caller output: #{output}"
|
602
602
|
output * 2
|
603
603
|
end
|
604
604
|
.tap do |tree|
|
@@ -608,20 +608,20 @@ Node::HooksSample.new
|
|
608
608
|
end
|
609
609
|
```
|
610
610
|
|
611
|
-
Run `examples/hooks-
|
611
|
+
Run `examples/hooks-caller.rb`:
|
612
612
|
```sh
|
613
|
-
% ruby examples/hooks-
|
614
|
-
|
613
|
+
% ruby examples/hooks-caller.rb
|
614
|
+
before_caller input: 1
|
615
615
|
external input: 2
|
616
|
-
|
617
|
-
|
618
|
-
|
616
|
+
around_caller input: 2
|
617
|
+
around_caller output: 4
|
618
|
+
after_caller output: 8
|
619
619
|
result: 16
|
620
620
|
```
|
621
621
|
|
622
622
|
## Contributing
|
623
623
|
|
624
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/jsmmr/
|
624
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jsmmr/ruby_callable_tree.
|
625
625
|
|
626
626
|
## License
|
627
627
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'callable_tree'
|
4
|
+
|
5
|
+
Root =
|
6
|
+
CallableTree::Node::Internal::Builder
|
7
|
+
.new
|
8
|
+
.hookable
|
9
|
+
.build
|
10
|
+
|
11
|
+
Root
|
12
|
+
.new
|
13
|
+
.before_caller do |input, **_options|
|
14
|
+
puts "before_caller input: #{input}"
|
15
|
+
input + 1
|
16
|
+
end
|
17
|
+
.append(
|
18
|
+
# anonymous external node
|
19
|
+
lambda do |input, **_options|
|
20
|
+
puts "external input: #{input}"
|
21
|
+
input * 2
|
22
|
+
end
|
23
|
+
)
|
24
|
+
.around_caller do |input, **_options, &block|
|
25
|
+
puts "around_caller input: #{input}"
|
26
|
+
output = block.call
|
27
|
+
puts "around_caller output: #{output}"
|
28
|
+
output * input
|
29
|
+
end
|
30
|
+
.after_caller do |output, **_options|
|
31
|
+
puts "after_caller output: #{output}"
|
32
|
+
output * 2
|
33
|
+
end
|
34
|
+
.tap do |tree|
|
35
|
+
options = { foo: :bar }
|
36
|
+
output = tree.call(1, **options)
|
37
|
+
puts "result: #{output}"
|
38
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'callable_tree'
|
4
|
+
|
5
|
+
less_than = proc do |num|
|
6
|
+
# The following block call is equivalent to calling `super` in the class style.
|
7
|
+
proc { |input, &block| block.call(input) && input < num }
|
8
|
+
end
|
9
|
+
|
10
|
+
LessThan5 =
|
11
|
+
CallableTree::Node::Internal::Builder
|
12
|
+
.new
|
13
|
+
.matcher(&less_than.call(5))
|
14
|
+
.build
|
15
|
+
|
16
|
+
LessThan10 =
|
17
|
+
CallableTree::Node::Internal::Builder
|
18
|
+
.new
|
19
|
+
.matcher(&less_than.call(10))
|
20
|
+
.build
|
21
|
+
|
22
|
+
add = proc do |num|
|
23
|
+
proc { |input| input + num }
|
24
|
+
end
|
25
|
+
|
26
|
+
Add1 =
|
27
|
+
CallableTree::Node::External::Builder
|
28
|
+
.new
|
29
|
+
.caller(&add.call(1))
|
30
|
+
.build
|
31
|
+
|
32
|
+
subtract = proc do |num|
|
33
|
+
proc { |input| input - num }
|
34
|
+
end
|
35
|
+
|
36
|
+
Subtract1 =
|
37
|
+
CallableTree::Node::External::Builder
|
38
|
+
.new
|
39
|
+
.caller(&subtract.call(1))
|
40
|
+
.build
|
41
|
+
|
42
|
+
multiply = proc do |num|
|
43
|
+
proc { |input| input * num }
|
44
|
+
end
|
45
|
+
|
46
|
+
Multiply2 =
|
47
|
+
CallableTree::Node::External::Builder
|
48
|
+
.new
|
49
|
+
.caller(&multiply.call(2))
|
50
|
+
.build
|
51
|
+
|
52
|
+
Multiply3 =
|
53
|
+
CallableTree::Node::External::Builder
|
54
|
+
.new
|
55
|
+
.caller(&multiply.call(3))
|
56
|
+
.build
|
57
|
+
|
58
|
+
tree = CallableTree::Node::Root.new.broadcastable.append(
|
59
|
+
LessThan5.new.broadcastable.append(
|
60
|
+
Multiply2.new,
|
61
|
+
Add1.new
|
62
|
+
),
|
63
|
+
LessThan10.new.broadcastable.append(
|
64
|
+
Multiply3.new,
|
65
|
+
Subtract1.new
|
66
|
+
)
|
67
|
+
)
|
68
|
+
|
69
|
+
(0..10).each do |input|
|
70
|
+
output = tree.call(input)
|
71
|
+
puts "#{input} -> #{output}"
|
72
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'callable_tree'
|
4
|
+
|
5
|
+
less_than = proc do |num|
|
6
|
+
# The following block call is equivalent to calling `super` in the class style.
|
7
|
+
proc { |input, &block| block.call(input) && input < num }
|
8
|
+
end
|
9
|
+
|
10
|
+
LessThan5 =
|
11
|
+
CallableTree::Node::Internal::Builder
|
12
|
+
.new
|
13
|
+
.matcher(&less_than.call(5))
|
14
|
+
.build
|
15
|
+
|
16
|
+
LessThan10 =
|
17
|
+
CallableTree::Node::Internal::Builder
|
18
|
+
.new
|
19
|
+
.matcher(&less_than.call(10))
|
20
|
+
.build
|
21
|
+
|
22
|
+
add = proc do |num|
|
23
|
+
proc { |input| input + num }
|
24
|
+
end
|
25
|
+
|
26
|
+
Add1 =
|
27
|
+
CallableTree::Node::External::Builder
|
28
|
+
.new
|
29
|
+
.caller(&add.call(1))
|
30
|
+
.build
|
31
|
+
|
32
|
+
subtract = proc do |num|
|
33
|
+
proc { |input| input - num }
|
34
|
+
end
|
35
|
+
|
36
|
+
Subtract1 =
|
37
|
+
CallableTree::Node::External::Builder
|
38
|
+
.new
|
39
|
+
.caller(&subtract.call(1))
|
40
|
+
.build
|
41
|
+
|
42
|
+
multiply = proc do |num|
|
43
|
+
proc { |input| input * num }
|
44
|
+
end
|
45
|
+
|
46
|
+
Multiply2 =
|
47
|
+
CallableTree::Node::External::Builder
|
48
|
+
.new
|
49
|
+
.caller(&multiply.call(2))
|
50
|
+
.build
|
51
|
+
|
52
|
+
Multiply3 =
|
53
|
+
CallableTree::Node::External::Builder
|
54
|
+
.new
|
55
|
+
.caller(&multiply.call(3))
|
56
|
+
.build
|
57
|
+
|
58
|
+
tree = CallableTree::Node::Root.new.composable.append(
|
59
|
+
LessThan5.new.composable.append(
|
60
|
+
Multiply2.new,
|
61
|
+
Add1.new
|
62
|
+
),
|
63
|
+
LessThan10.new.composable.append(
|
64
|
+
Multiply3.new,
|
65
|
+
Subtract1.new
|
66
|
+
)
|
67
|
+
)
|
68
|
+
|
69
|
+
(0..10).each do |input|
|
70
|
+
output = tree.call(input)
|
71
|
+
puts "#{input} -> #{output}"
|
72
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'callable_tree'
|
4
|
+
require 'json'
|
5
|
+
require 'rexml/document'
|
6
|
+
|
7
|
+
JSONParser =
|
8
|
+
CallableTree::Node::Internal::Builder
|
9
|
+
.new
|
10
|
+
.matcher do |input, **_options|
|
11
|
+
File.extname(input) == '.json'
|
12
|
+
end
|
13
|
+
.caller do |input, **options, &block|
|
14
|
+
File.open(input) do |file|
|
15
|
+
json = ::JSON.load(file)
|
16
|
+
# The following block call is equivalent to calling `super` in the class style.
|
17
|
+
block.call(json, **options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
.terminator do
|
21
|
+
true
|
22
|
+
end
|
23
|
+
.build
|
24
|
+
|
25
|
+
XMLParser =
|
26
|
+
CallableTree::Node::Internal::Builder
|
27
|
+
.new
|
28
|
+
.matcher do |input, **_options|
|
29
|
+
File.extname(input) == '.xml'
|
30
|
+
end
|
31
|
+
.caller do |input, **options, &block|
|
32
|
+
File.open(input) do |file|
|
33
|
+
# The following block call is equivalent to calling `super` in the class style.
|
34
|
+
block.call(REXML::Document.new(file), **options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
.terminator do
|
38
|
+
true
|
39
|
+
end
|
40
|
+
.build
|
41
|
+
|
42
|
+
def build_json_scraper(type)
|
43
|
+
CallableTree::Node::External::Builder
|
44
|
+
.new
|
45
|
+
.matcher do |input, **_options|
|
46
|
+
!!input[type.to_s]
|
47
|
+
end
|
48
|
+
.caller do |input, **_options|
|
49
|
+
input[type.to_s]
|
50
|
+
.map { |element| [element['name'], element['emoji']] }
|
51
|
+
.to_h
|
52
|
+
end
|
53
|
+
.build
|
54
|
+
end
|
55
|
+
|
56
|
+
AnimalsJSONScraper = build_json_scraper(:animals)
|
57
|
+
FruitsJSONScraper = build_json_scraper(:fruits)
|
58
|
+
|
59
|
+
def build_xml_scraper(type)
|
60
|
+
CallableTree::Node::External::Builder
|
61
|
+
.new
|
62
|
+
.matcher do |input, **_options|
|
63
|
+
!input.get_elements("//#{type}").empty?
|
64
|
+
end
|
65
|
+
.caller do |input, **_options|
|
66
|
+
input
|
67
|
+
.get_elements("//#{type}")
|
68
|
+
.first
|
69
|
+
.map { |element| [element['name'], element['emoji']] }
|
70
|
+
.to_h
|
71
|
+
end
|
72
|
+
.build
|
73
|
+
end
|
74
|
+
|
75
|
+
AnimalsXMLScraper = build_xml_scraper(:animals)
|
76
|
+
FruitsXMLScraper = build_xml_scraper(:fruits)
|
77
|
+
|
78
|
+
tree = CallableTree::Node::Root.new.seekable.append(
|
79
|
+
JSONParser.new.seekable.append(
|
80
|
+
AnimalsJSONScraper.new,
|
81
|
+
FruitsJSONScraper.new
|
82
|
+
),
|
83
|
+
XMLParser.new.seekable.append(
|
84
|
+
AnimalsXMLScraper.new,
|
85
|
+
FruitsXMLScraper.new
|
86
|
+
)
|
87
|
+
)
|
88
|
+
|
89
|
+
Dir.glob("#{__dir__}/../docs/*") do |file|
|
90
|
+
options = { foo: :bar }
|
91
|
+
pp tree.call(file, **options)
|
92
|
+
puts '---'
|
93
|
+
end
|