callable_tree 0.1.0 → 0.1.1
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/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +124 -13
- data/callable_tree.gemspec +3 -3
- data/examples/example1.rb +1 -1
- data/examples/example2.rb +1 -1
- data/examples/example3.rb +1 -1
- data/examples/example4.rb +1 -1
- data/examples/example6.rb +101 -0
- data/lib/callable_tree.rb +3 -1
- data/lib/callable_tree/node/internal.rb +20 -38
- data/lib/callable_tree/node/internal/broadcast.rb +19 -0
- data/lib/callable_tree/node/internal/seek.rb +23 -0
- data/lib/callable_tree/version.rb +1 -1
- metadata +8 -6
- data/lib/callable_tree/node/branch.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea52457dd99aca79ec45ac97716f53824b14dde4d479486b9d9fa6571a714c76
|
4
|
+
data.tar.gz: 4fa5ee37a4a061b7c92f3373131b588bd30f12a351f344646dab2ec2d1089718
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f6e91b80e81f89d0e8f1c15ac5043de2b100245232de6b3584e900d1378952ad91442e4a55f80c59cfe8a01e5a9b34cf277b3a213290cf0b5aa8e0985edc7ca
|
7
|
+
data.tar.gz: 2a89b0e60761fa826c1e083b34f24138693c9f44743c0c3c018f6dcbf330a6471481421dc9c99b4f4d5ae2f410aaeec293bed4ed46f10f28482280ea582f895a
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -136,7 +136,7 @@ tree = CallableTree::Node::Root.new.append(
|
|
136
136
|
|
137
137
|
Dir.glob(__dir__ + '/docs/*') do |file|
|
138
138
|
options = { foo: :bar }
|
139
|
-
|
139
|
+
pp tree.call(file, **options)
|
140
140
|
puts '---'
|
141
141
|
end
|
142
142
|
```
|
@@ -181,13 +181,25 @@ tree = CallableTree::Node::Root.new.append(
|
|
181
181
|
Run `examples/example2.rb`:
|
182
182
|
```sh
|
183
183
|
% ruby examples/example2.rb
|
184
|
-
#<struct CallableTree::Node::External::Output
|
184
|
+
#<struct CallableTree::Node::External::Output
|
185
|
+
value={"Dog"=>"🐶", "Cat"=>"🐱"},
|
186
|
+
options={:foo=>:bar},
|
187
|
+
routes=[Node::JSON::Scraper, Node::JSON::Parser, CallableTree::Node::Root]>
|
185
188
|
---
|
186
|
-
#<struct CallableTree::Node::External::Output
|
189
|
+
#<struct CallableTree::Node::External::Output
|
190
|
+
value={"Dog"=>"🐶", "Cat"=>"🐱"},
|
191
|
+
options={:foo=>:bar},
|
192
|
+
routes=[Node::XML::Scraper, Node::XML::Parser, CallableTree::Node::Root]>
|
187
193
|
---
|
188
|
-
#<struct CallableTree::Node::External::Output
|
194
|
+
#<struct CallableTree::Node::External::Output
|
195
|
+
value={"Red Apple"=>"🍎", "Green Apple"=>"🍏"},
|
196
|
+
options={:foo=>:bar},
|
197
|
+
routes=[Node::JSON::Scraper, Node::JSON::Parser, CallableTree::Node::Root]>
|
189
198
|
---
|
190
|
-
#<struct CallableTree::Node::External::Output
|
199
|
+
#<struct CallableTree::Node::External::Output
|
200
|
+
value={"Red Apple"=>"🍎", "Green Apple"=>"🍏"},
|
201
|
+
options={:foo=>:bar},
|
202
|
+
routes=[Node::XML::Scraper, Node::XML::Parser, CallableTree::Node::Root]>
|
191
203
|
---
|
192
204
|
```
|
193
205
|
|
@@ -257,13 +269,45 @@ end
|
|
257
269
|
Run `examples/example3.rb`:
|
258
270
|
```sh
|
259
271
|
% ruby examples/example3.rb
|
260
|
-
#<struct CallableTree::Node::External::Output
|
272
|
+
#<struct CallableTree::Node::External::Output
|
273
|
+
value={"Dog"=>"🐶", "Cat"=>"🐱"},
|
274
|
+
options={:foo=>:bar},
|
275
|
+
routes=
|
276
|
+
[#<Node::Identity:0x00007fb4378a9718
|
277
|
+
@klass=Node::JSON::Scraper,
|
278
|
+
@type=:animals>,
|
279
|
+
Node::JSON::Parser,
|
280
|
+
CallableTree::Node::Root]>
|
261
281
|
---
|
262
|
-
#<struct CallableTree::Node::External::Output
|
282
|
+
#<struct CallableTree::Node::External::Output
|
283
|
+
value={"Dog"=>"🐶", "Cat"=>"🐱"},
|
284
|
+
options={:foo=>:bar},
|
285
|
+
routes=
|
286
|
+
[#<Node::Identity:0x00007fb41002b6d0
|
287
|
+
@klass=Node::XML::Scraper,
|
288
|
+
@type=:animals>,
|
289
|
+
Node::XML::Parser,
|
290
|
+
CallableTree::Node::Root]>
|
263
291
|
---
|
264
|
-
#<struct CallableTree::Node::External::Output
|
292
|
+
#<struct CallableTree::Node::External::Output
|
293
|
+
value={"Red Apple"=>"🍎", "Green Apple"=>"🍏"},
|
294
|
+
options={:foo=>:bar},
|
295
|
+
routes=
|
296
|
+
[#<Node::Identity:0x00007fb41001b3e8
|
297
|
+
@klass=Node::JSON::Scraper,
|
298
|
+
@type=:fruits>,
|
299
|
+
Node::JSON::Parser,
|
300
|
+
CallableTree::Node::Root]>
|
265
301
|
---
|
266
|
-
#<struct CallableTree::Node::External::Output
|
302
|
+
#<struct CallableTree::Node::External::Output
|
303
|
+
value={"Red Apple"=>"🍎", "Green Apple"=>"🍏"},
|
304
|
+
options={:foo=>:bar},
|
305
|
+
routes=
|
306
|
+
[#<Node::Identity:0x00007fb410049d38
|
307
|
+
@klass=Node::XML::Scraper,
|
308
|
+
@type=:fruits>,
|
309
|
+
Node::XML::Parser,
|
310
|
+
CallableTree::Node::Root]>
|
267
311
|
---
|
268
312
|
```
|
269
313
|
|
@@ -351,21 +395,45 @@ Run `examples/example4.rb`:
|
|
351
395
|
* Node::JSON::Scraper(animals): [matched: true]
|
352
396
|
Input : {"animals"=>[{"name"=>"Dog", "emoji"=>"🐶"}, {"name"=>"Cat", "emoji"=>"🐱"}]}
|
353
397
|
Output: {"Dog"=>"🐶", "Cat"=>"🐱"}
|
354
|
-
#<struct CallableTree::Node::External::Output
|
398
|
+
#<struct CallableTree::Node::External::Output
|
399
|
+
value={"Dog"=>"🐶", "Cat"=>"🐱"},
|
400
|
+
options={:foo=>:bar},
|
401
|
+
routes=
|
402
|
+
[#<Node::Identity:0x00007ffd840347b8
|
403
|
+
@klass=Node::JSON::Scraper,
|
404
|
+
@type=:animals>,
|
405
|
+
Node::JSON::Parser,
|
406
|
+
CallableTree::Node::Root]>
|
355
407
|
---
|
356
408
|
* Node::JSON::Parser: [matched: false]
|
357
409
|
* Node::XML::Parser: [matched: true]
|
358
410
|
* Node::XML::Scraper(animals): [matched: true]
|
359
411
|
Input : <root><animals><animal emoji='🐶' name='Dog'/><animal emoji='🐱' name='Cat'/></animals></root>
|
360
412
|
Output: {"Dog"=>"🐶", "Cat"=>"🐱"}
|
361
|
-
#<struct CallableTree::Node::External::Output
|
413
|
+
#<struct CallableTree::Node::External::Output
|
414
|
+
value={"Dog"=>"🐶", "Cat"=>"🐱"},
|
415
|
+
options={:foo=>:bar},
|
416
|
+
routes=
|
417
|
+
[#<Node::Identity:0x00007ffd7403f1f0
|
418
|
+
@klass=Node::XML::Scraper,
|
419
|
+
@type=:animals>,
|
420
|
+
Node::XML::Parser,
|
421
|
+
CallableTree::Node::Root]>
|
362
422
|
---
|
363
423
|
* Node::JSON::Parser: [matched: true]
|
364
424
|
* Node::JSON::Scraper(animals): [matched: false]
|
365
425
|
* Node::JSON::Scraper(fruits): [matched: true]
|
366
426
|
Input : {"fruits"=>[{"name"=>"Red Apple", "emoji"=>"🍎"}, {"name"=>"Green Apple", "emoji"=>"🍏"}]}
|
367
427
|
Output: {"Red Apple"=>"🍎", "Green Apple"=>"🍏"}
|
368
|
-
#<struct CallableTree::Node::External::Output
|
428
|
+
#<struct CallableTree::Node::External::Output
|
429
|
+
value={"Red Apple"=>"🍎", "Green Apple"=>"🍏"},
|
430
|
+
options={:foo=>:bar},
|
431
|
+
routes=
|
432
|
+
[#<Node::Identity:0x00007ffd8512bdf0
|
433
|
+
@klass=Node::JSON::Scraper,
|
434
|
+
@type=:fruits>,
|
435
|
+
Node::JSON::Parser,
|
436
|
+
CallableTree::Node::Root]>
|
369
437
|
---
|
370
438
|
* Node::JSON::Parser: [matched: false]
|
371
439
|
* Node::XML::Parser: [matched: true]
|
@@ -373,7 +441,15 @@ Run `examples/example4.rb`:
|
|
373
441
|
* Node::XML::Scraper(fruits): [matched: true]
|
374
442
|
Input : <root><fruits><fruit emoji='🍎' name='Red Apple'/><fruit emoji='🍏' name='Green Apple'/></fruits></root>
|
375
443
|
Output: {"Red Apple"=>"🍎", "Green Apple"=>"🍏"}
|
376
|
-
#<struct CallableTree::Node::External::Output
|
444
|
+
#<struct CallableTree::Node::External::Output
|
445
|
+
value={"Red Apple"=>"🍎", "Green Apple"=>"🍏"},
|
446
|
+
options={:foo=>:bar},
|
447
|
+
routes=
|
448
|
+
[#<Node::Identity:0x00007ffd8407a740
|
449
|
+
@klass=Node::XML::Scraper,
|
450
|
+
@type=:fruits>,
|
451
|
+
Node::XML::Parser,
|
452
|
+
CallableTree::Node::Root]>
|
377
453
|
---
|
378
454
|
```
|
379
455
|
|
@@ -427,6 +503,41 @@ after_call output: 8
|
|
427
503
|
result: 16
|
428
504
|
```
|
429
505
|
|
506
|
+
#### `CallableTree::Node::Internal#broadcast` (experimental)
|
507
|
+
|
508
|
+
If you want to call and output all child nodes of the internal node, call it. Broadcast strategy ignores the `terminate?` method of the child node.
|
509
|
+
|
510
|
+
`examples/example6.rb`:
|
511
|
+
```ruby
|
512
|
+
...
|
513
|
+
|
514
|
+
tree = CallableTree::Node::Root.new.append(
|
515
|
+
Node::JSON::Parser.new.append(
|
516
|
+
Node::JSON::Scraper.new(type: :animals),
|
517
|
+
Node::JSON::Scraper.new(type: :fruits)
|
518
|
+
).broadcast,
|
519
|
+
Node::XML::Parser.new.append(
|
520
|
+
Node::XML::Scraper.new(type: :animals),
|
521
|
+
Node::XML::Scraper.new(type: :fruits)
|
522
|
+
).broadcast
|
523
|
+
)
|
524
|
+
|
525
|
+
...
|
526
|
+
```
|
527
|
+
|
528
|
+
Run `examples/example6.rb`:
|
529
|
+
```sh
|
530
|
+
% ruby examples/example6.rb
|
531
|
+
[{"Dog"=>"🐶", "Cat"=>"🐱"}, nil]
|
532
|
+
---
|
533
|
+
[{"Dog"=>"🐶", "Cat"=>"🐱"}, nil]
|
534
|
+
---
|
535
|
+
[nil, {"Red Apple"=>"🍎", "Green Apple"=>"🍏"}]
|
536
|
+
---
|
537
|
+
[nil, {"Red Apple"=>"🍎", "Green Apple"=>"🍏"}]
|
538
|
+
---
|
539
|
+
```
|
540
|
+
|
430
541
|
## Contributing
|
431
542
|
|
432
543
|
Bug reports and pull requests are welcome on GitHub at https://github.com/jsmmr/callable_tree.
|
data/callable_tree.gemspec
CHANGED
@@ -8,15 +8,15 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['jsmmr']
|
9
9
|
spec.email = ['jsmmr@icloud.com']
|
10
10
|
|
11
|
-
spec.summary = 'Builds a tree by linking callable nodes. The nodes that match the calling condition are called in a chain from the root node to the leaf node.
|
12
|
-
spec.description = 'Builds a tree by linking callable nodes. The nodes that match the calling condition are called in a chain from the root node to the leaf node.
|
11
|
+
spec.summary = 'Builds a tree by linking callable nodes. The nodes that match the calling condition are called in a chain from the root node to the leaf node. These are like nested case statements.'
|
12
|
+
spec.description = 'Builds a tree by linking callable nodes. The nodes that match the calling condition are called in a chain from the root node to the leaf node. These are like nested case statements.'
|
13
13
|
spec.homepage = 'https://github.com/jsmmr/ruby_callable_tree'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
|
16
16
|
|
17
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
18
18
|
spec.metadata['source_code_uri'] = 'https://github.com/jsmmr/ruby_callable_tree'
|
19
|
-
spec.metadata['changelog_uri'] = 'https://github.com/jsmmr/ruby_callable_tree/CHANGELOG.md'
|
19
|
+
spec.metadata['changelog_uri'] = 'https://github.com/jsmmr/ruby_callable_tree/blob/v#{version}/CHANGELOG.md'
|
20
20
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
22
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
data/examples/example1.rb
CHANGED
data/examples/example2.rb
CHANGED
data/examples/example3.rb
CHANGED
data/examples/example4.rb
CHANGED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'callable_tree'
|
2
|
+
require 'json'
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
module Node
|
6
|
+
module JSON
|
7
|
+
class Parser
|
8
|
+
include CallableTree::Node::Internal
|
9
|
+
|
10
|
+
def match?(input, **options)
|
11
|
+
File.extname(input) == '.json'
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(input, **options)
|
15
|
+
File.open(input) do |file|
|
16
|
+
json = ::JSON.load(file)
|
17
|
+
super(json, **options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def terminate?(_output, **)
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Scraper
|
27
|
+
include CallableTree::Node::External
|
28
|
+
|
29
|
+
def initialize(type:)
|
30
|
+
@type = type
|
31
|
+
end
|
32
|
+
|
33
|
+
def match?(input, **options)
|
34
|
+
!!input[@type.to_s]
|
35
|
+
end
|
36
|
+
|
37
|
+
def call(input, **options)
|
38
|
+
input[@type.to_s]
|
39
|
+
.map { |element| [element['name'], element['emoji']] }
|
40
|
+
.to_h
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module XML
|
46
|
+
class Parser
|
47
|
+
include CallableTree::Node::Internal
|
48
|
+
|
49
|
+
def match?(input, **options)
|
50
|
+
File.extname(input) == '.xml'
|
51
|
+
end
|
52
|
+
|
53
|
+
def call(input, **options)
|
54
|
+
File.open(input) do |file|
|
55
|
+
super(REXML::Document.new(file), **options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def terminate?(_output, **)
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Scraper
|
65
|
+
include CallableTree::Node::External
|
66
|
+
|
67
|
+
def initialize(type:)
|
68
|
+
@type = type
|
69
|
+
end
|
70
|
+
|
71
|
+
def match?(input, **options)
|
72
|
+
!input.get_elements("//#{@type}").empty?
|
73
|
+
end
|
74
|
+
|
75
|
+
def call(input, **options)
|
76
|
+
input
|
77
|
+
.get_elements("//#{@type}")
|
78
|
+
.first
|
79
|
+
.map { |element| [element['name'], element['emoji']] }
|
80
|
+
.to_h
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
tree = CallableTree::Node::Root.new.append(
|
87
|
+
Node::JSON::Parser.new.append(
|
88
|
+
Node::JSON::Scraper.new(type: :animals),
|
89
|
+
Node::JSON::Scraper.new(type: :fruits)
|
90
|
+
).broadcast,
|
91
|
+
Node::XML::Parser.new.append(
|
92
|
+
Node::XML::Scraper.new(type: :animals),
|
93
|
+
Node::XML::Scraper.new(type: :fruits)
|
94
|
+
).broadcast
|
95
|
+
)
|
96
|
+
|
97
|
+
Dir.glob(__dir__ + '/docs/*') do |file|
|
98
|
+
options = { foo: :bar }
|
99
|
+
pp tree.call(file, **options)
|
100
|
+
puts '---'
|
101
|
+
end
|
data/lib/callable_tree.rb
CHANGED
@@ -7,8 +7,10 @@ end
|
|
7
7
|
require 'forwardable'
|
8
8
|
require_relative 'callable_tree/version'
|
9
9
|
require_relative 'callable_tree/node'
|
10
|
+
require_relative 'callable_tree/node/hooks/call'
|
11
|
+
require_relative 'callable_tree/node/internal/broadcast'
|
12
|
+
require_relative 'callable_tree/node/internal/seek'
|
10
13
|
require_relative 'callable_tree/node/external/verbose'
|
11
14
|
require_relative 'callable_tree/node/external'
|
12
|
-
require_relative 'callable_tree/node/hooks/call'
|
13
15
|
require_relative 'callable_tree/node/internal'
|
14
16
|
require_relative 'callable_tree/node/root'
|
@@ -31,54 +31,36 @@ module CallableTree
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def call(input = nil, **options)
|
34
|
-
children
|
35
|
-
.lazy
|
36
|
-
.map { |node| Input.new(input, options, node) }
|
37
|
-
.select { |input| input.valid? }
|
38
|
-
.map { |input| input.call }
|
39
|
-
.select { |output| output.valid? }
|
40
|
-
.map { |output| output.call }
|
41
|
-
.first
|
34
|
+
strategy.call(children, input: input, options: options)
|
42
35
|
end
|
43
36
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
def valid?
|
52
|
-
@node.match?(@value, **@options)
|
53
|
-
end
|
54
|
-
|
55
|
-
def call
|
56
|
-
value = @node.call(@value, **@options)
|
57
|
-
Output.new(value, @options, @node)
|
37
|
+
def seek
|
38
|
+
if strategy.is_a?(Seek)
|
39
|
+
self
|
40
|
+
else
|
41
|
+
clone.tap do |node|
|
42
|
+
node.send(:strategy=, Seek.new)
|
43
|
+
end
|
58
44
|
end
|
59
45
|
end
|
60
46
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def valid?
|
69
|
-
@node.terminate?(@value, **@options)
|
70
|
-
end
|
71
|
-
|
72
|
-
def call
|
73
|
-
@value
|
47
|
+
def broadcast
|
48
|
+
if strategy.is_a?(Broadcast)
|
49
|
+
self
|
50
|
+
else
|
51
|
+
clone.tap do |node|
|
52
|
+
node.send(:strategy=, Broadcast.new)
|
53
|
+
end
|
74
54
|
end
|
75
55
|
end
|
76
56
|
|
77
|
-
private_constant :Input, :Output
|
78
|
-
|
79
57
|
private
|
80
58
|
|
81
|
-
attr_writer :children
|
59
|
+
attr_writer :children, :strategy
|
60
|
+
|
61
|
+
def strategy
|
62
|
+
@strategy ||= Seek.new
|
63
|
+
end
|
82
64
|
|
83
65
|
def initialize_copy(_node)
|
84
66
|
super
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CallableTree
|
4
|
+
module Node
|
5
|
+
module Internal
|
6
|
+
class Broadcast
|
7
|
+
def call(nodes, input:, options:)
|
8
|
+
nodes.map do |node|
|
9
|
+
if node.match?(input, **options)
|
10
|
+
node.call(input, **options)
|
11
|
+
else
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CallableTree
|
4
|
+
module Node
|
5
|
+
module Internal
|
6
|
+
class Seek
|
7
|
+
def call(nodes, input:, options:)
|
8
|
+
nodes
|
9
|
+
.lazy
|
10
|
+
.select { |node| node.match?(input, **options) }
|
11
|
+
.map do |node|
|
12
|
+
output = node.call(input, **options)
|
13
|
+
terminated = node.terminate?(output, **options)
|
14
|
+
[output, terminated]
|
15
|
+
end
|
16
|
+
.select { |_output, terminated| terminated }
|
17
|
+
.map { |output, _terminated| output }
|
18
|
+
.first
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: callable_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jsmmr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-05-
|
11
|
+
date: 2021-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Builds a tree by linking callable nodes. The nodes that match the calling
|
14
|
-
condition are called in a chain from the root node to the leaf node.
|
14
|
+
condition are called in a chain from the root node to the leaf node. These are like
|
15
15
|
nested case statements.
|
16
16
|
email:
|
17
17
|
- jsmmr@icloud.com
|
@@ -41,13 +41,15 @@ files:
|
|
41
41
|
- examples/example3.rb
|
42
42
|
- examples/example4.rb
|
43
43
|
- examples/example5.rb
|
44
|
+
- examples/example6.rb
|
44
45
|
- lib/callable_tree.rb
|
45
46
|
- lib/callable_tree/node.rb
|
46
|
-
- lib/callable_tree/node/branch.rb
|
47
47
|
- lib/callable_tree/node/external.rb
|
48
48
|
- lib/callable_tree/node/external/verbose.rb
|
49
49
|
- lib/callable_tree/node/hooks/call.rb
|
50
50
|
- lib/callable_tree/node/internal.rb
|
51
|
+
- lib/callable_tree/node/internal/broadcast.rb
|
52
|
+
- lib/callable_tree/node/internal/seek.rb
|
51
53
|
- lib/callable_tree/node/root.rb
|
52
54
|
- lib/callable_tree/version.rb
|
53
55
|
homepage: https://github.com/jsmmr/ruby_callable_tree
|
@@ -56,7 +58,7 @@ licenses:
|
|
56
58
|
metadata:
|
57
59
|
homepage_uri: https://github.com/jsmmr/ruby_callable_tree
|
58
60
|
source_code_uri: https://github.com/jsmmr/ruby_callable_tree
|
59
|
-
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/CHANGELOG.md
|
61
|
+
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v#{version}/CHANGELOG.md
|
60
62
|
post_install_message:
|
61
63
|
rdoc_options: []
|
62
64
|
require_paths:
|
@@ -76,6 +78,6 @@ rubygems_version: 3.2.16
|
|
76
78
|
signing_key:
|
77
79
|
specification_version: 4
|
78
80
|
summary: Builds a tree by linking callable nodes. The nodes that match the calling
|
79
|
-
condition are called in a chain from the root node to the leaf node.
|
81
|
+
condition are called in a chain from the root node to the leaf node. These are like
|
80
82
|
nested case statements.
|
81
83
|
test_files: []
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CallableTree
|
4
|
-
module Node
|
5
|
-
module Branch
|
6
|
-
attr_reader :parent
|
7
|
-
|
8
|
-
def ancestors
|
9
|
-
::Enumerator.new do |y|
|
10
|
-
node = self
|
11
|
-
while node = node&.parent
|
12
|
-
y << node
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def routes
|
18
|
-
::Enumerator.new do |y|
|
19
|
-
y << self.class
|
20
|
-
ancestors.each { |node| y << node.class }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def depth
|
25
|
-
parent.nil? ? 0 : parent.depth + 1
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
attr_writer :parent
|
31
|
-
end
|
32
|
-
|
33
|
-
private_constant :Branch
|
34
|
-
end
|
35
|
-
end
|