callable_tree 0.3.3 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3feea9db6a3844729a1644e56d60cc0cf8961e95e5ae5d58fcf4eb10eab6c80d
4
- data.tar.gz: 6de275fcb284556be10c22cea0e310adecadebab11bd5b884b736b809543120c
3
+ metadata.gz: 2a83d353d4049c06aa0a0d5f18f56c5c6d0d909cd4a54f6bbcba7faf4e835c0f
4
+ data.tar.gz: ab803f4e8b613a0ceb5e4d3ca21d38e1a5cf2a238db61384c0ec85b437fd7d73
5
5
  SHA512:
6
- metadata.gz: 14883eaed6a4655f62908ae53dabadd007e56befb50cb8d5b02790d91441afe3749ecf00019709a5ba39b8bfaafeaa8e475a318e62d1a93f21511ef3611d4238
7
- data.tar.gz: b58152e34c1e7b7c3f9941715d7f512f71d40b1abbacbb7481e965ceb34969117c56b4a9ee218ed62f087dedc7d85ffdde1d9f43ab6beb25aa6da8b89b9dfde1
6
+ metadata.gz: 27dd59b36d4ebc99395df901a900d72510928f5f4a9603405b83f54d0566652fda2253bcda7bf6efee1ad0363919c5ec7bb63a1ec1e0efc488e656d6ff1bce3a
7
+ data.tar.gz: 3029f92901053688715cffce367d0e44f01402743413dfd38dc52c6c63221094fe2d3774cf2b1b98d66b84dd6837c8d6e6430c228ce3f196e60f9222286a3a56
@@ -11,7 +11,7 @@ jobs:
11
11
  - uses: ruby/setup-ruby@v1
12
12
  with:
13
13
  ruby-version: ${{ matrix.ruby }}
14
- - run: gem install bundler:2.3.3
14
+ - run: gem install bundler:2.3.7
15
15
  - uses: actions/cache@v2
16
16
  with:
17
17
  path: vendor/bundle
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.0
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.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-19
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.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#seek` (default)
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-seek.rb`:
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 `seek` method call can be omitted since it is the default strategy.
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
- ),#.seek,
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
- )#.seek
142
- )#.seek
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-seek.rb`:
151
+ Run `examples/internal-seekable.rb`:
152
152
  ```sh
153
- % ruby examples/internal-seek.rb
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#broadcast`
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-broadcast.rb`:
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
- ).broadcast,
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
- ).broadcast
193
- ).broadcast
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-broadcast.rb`:
202
+ Run `examples/internal-broadcastable.rb`:
203
203
  ```sh
204
- % ruby examples/internal-broadcast.rb
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#compose`
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-compose.rb`:
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
- ).compose,
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
- ).compose
247
- ).compose
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-compose.rb`:
256
+ Run `examples/internal-composable.rb`:
257
257
  ```sh
258
- % ruby examples/internal-compose.rb
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::Call` (experimental)
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::Call
578
+ prepend CallableTree::Node::Hooks::Caller
579
579
  end
580
580
  end
581
581
 
582
582
  Node::HooksSample.new
583
- .before_call do |input, **_options|
584
- puts "before_call input: #{input}";
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
- .around_call do |input, **_options, &block|
595
- puts "around_call input: #{input}"
594
+ .around_caller do |input, **_options, &block|
595
+ puts "around_caller input: #{input}"
596
596
  output = block.call
597
- puts "around_call output: #{output}"
597
+ puts "around_caller output: #{output}"
598
598
  output * input
599
599
  end
600
- .after_call do |output, **_options|
601
- puts "after_call output: #{output}"
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-call.rb`:
611
+ Run `examples/hooks-caller.rb`:
612
612
  ```sh
613
- % ruby examples/hooks-call.rb
614
- before_call input: 1
613
+ % ruby examples/hooks-caller.rb
614
+ before_caller input: 1
615
615
  external input: 2
616
- around_call input: 2
617
- around_call output: 4
618
- after_call output: 8
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/callable_tree.
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