callable_tree 0.3.9 → 0.3.10
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 +2 -2
- data/.ruby-version +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +14 -14
- data/README.md +14 -14
- data/examples/builder/external-verbosify.rb +1 -1
- data/examples/builder/identity.rb +1 -1
- data/examples/builder/internal-seekable.rb +1 -1
- data/examples/builder/logging.rb +14 -14
- data/examples/class/logging.rb +13 -13
- data/lib/callable_tree/node/external.rb +4 -4
- data/lib/callable_tree/node/internal/strategy/broadcast.rb +7 -14
- data/lib/callable_tree/node/internal/strategy/compose.rb +4 -9
- data/lib/callable_tree/node/internal/strategy/seek.rb +4 -9
- data/lib/callable_tree/node/internal/strategy.rb +25 -3
- data/lib/callable_tree/node/internal/strategyable.rb +117 -0
- data/lib/callable_tree/node/internal.rb +13 -86
- data/lib/callable_tree/node.rb +1 -1
- data/lib/callable_tree/version.rb +1 -1
- data/lib/callable_tree.rb +1 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dccb97d338f0f2d01a1986b2b0418660467fde837a79bd06b67f0df235bee5f2
|
4
|
+
data.tar.gz: 5002a705a96346ea92704eea7c8282beead6d4ef62c7ff2a9865f4b24e629faa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d16dd16df13a3c5f5b6a4c5292d50acbf571482dbde0496e29d69d745ad887b4274e84edd5ace4707fe2bdf54d324389a2d1b662ffb94d1e430e5819762f40d
|
7
|
+
data.tar.gz: f531ae0eaaf51065f69e61a8eb4e70b83ba32bc280d699c2fce00b4b4a9c1ac3d8fb5fe61bcb3a7c40805edae1a26c4943bd9d09a4d4760a4e0f67a3dd4f62e9
|
data/.github/workflows/build.yml
CHANGED
@@ -5,13 +5,13 @@ jobs:
|
|
5
5
|
runs-on: ubuntu-latest
|
6
6
|
strategy:
|
7
7
|
matrix:
|
8
|
-
ruby: ['2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2
|
8
|
+
ruby: ['2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2']
|
9
9
|
steps:
|
10
10
|
- uses: actions/checkout@v3
|
11
11
|
- uses: ruby/setup-ruby@v1
|
12
12
|
with:
|
13
13
|
ruby-version: ${{ matrix.ruby }}
|
14
|
-
- run: gem install bundler:2.3.
|
14
|
+
- run: gem install bundler:2.3.26
|
15
15
|
- uses: actions/cache@v3
|
16
16
|
with:
|
17
17
|
path: vendor/bundle
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.10] - 2022-12-30
|
4
|
+
|
5
|
+
- Change `CallableTree::Node::Internal#broadcastable` to take `matchable` keyword parameter as boolean. It defaults to `true`, which is the same behavior as before.
|
6
|
+
- Change `CallableTree::Node::Internal#composable` to take `matchable` keyword parameter as boolean. It defaults to `true`, which is the same behavior as before.
|
7
|
+
- Change `CallableTree::Node::Internal#seekable` to take `matchable` keyword parameter as boolean. It defaults to `true`, which is the same behavior as before.
|
8
|
+
|
3
9
|
## [0.3.9] - 2022-11-06
|
4
10
|
|
5
11
|
- Change `CallableTree::Node::Internal#broadcastable` to take `terminable` keyword parameter as boolean. It defaults to `false`, which is the same behavior as before.
|
data/Gemfile.lock
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
callable_tree (0.3.
|
4
|
+
callable_tree (0.3.10)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
diff-lcs (1.5.0)
|
10
10
|
rake (13.0.6)
|
11
|
-
rspec (3.
|
12
|
-
rspec-core (~> 3.
|
13
|
-
rspec-expectations (~> 3.
|
14
|
-
rspec-mocks (~> 3.
|
15
|
-
rspec-core (3.
|
16
|
-
rspec-support (~> 3.
|
17
|
-
rspec-expectations (3.
|
11
|
+
rspec (3.12.0)
|
12
|
+
rspec-core (~> 3.12.0)
|
13
|
+
rspec-expectations (~> 3.12.0)
|
14
|
+
rspec-mocks (~> 3.12.0)
|
15
|
+
rspec-core (3.12.0)
|
16
|
+
rspec-support (~> 3.12.0)
|
17
|
+
rspec-expectations (3.12.1)
|
18
18
|
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
-
rspec-support (~> 3.
|
20
|
-
rspec-mocks (3.
|
19
|
+
rspec-support (~> 3.12.0)
|
20
|
+
rspec-mocks (3.12.1)
|
21
21
|
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
-
rspec-support (~> 3.
|
23
|
-
rspec-support (3.
|
22
|
+
rspec-support (~> 3.12.0)
|
23
|
+
rspec-support (3.12.0)
|
24
24
|
|
25
25
|
PLATFORMS
|
26
|
-
x86_64-darwin-
|
26
|
+
x86_64-darwin-22
|
27
27
|
|
28
28
|
DEPENDENCIES
|
29
29
|
callable_tree!
|
@@ -31,4 +31,4 @@ DEPENDENCIES
|
|
31
31
|
rspec (~> 3.0)
|
32
32
|
|
33
33
|
BUNDLED WITH
|
34
|
-
2.3.
|
34
|
+
2.3.26
|
data/README.md
CHANGED
@@ -659,19 +659,19 @@ module Logging
|
|
659
659
|
matched
|
660
660
|
end
|
661
661
|
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
662
|
+
return unless node.external?
|
663
|
+
|
664
|
+
node
|
665
|
+
.before_caller! do |input, *, _node_:, **|
|
666
|
+
input_prefix = INPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + INPUT_LABEL.length, BLANK)
|
667
|
+
puts "#{input_prefix} #{input}"
|
668
|
+
input
|
669
|
+
end
|
670
|
+
.after_caller! do |output, _node_:, **|
|
671
|
+
output_prefix = OUTPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + OUTPUT_LABEL.length, BLANK)
|
672
|
+
puts "#{output_prefix} #{output}"
|
673
|
+
output
|
674
|
+
end
|
675
675
|
end
|
676
676
|
end
|
677
677
|
|
@@ -778,7 +778,7 @@ end
|
|
778
778
|
...
|
779
779
|
```
|
780
780
|
|
781
|
-
Run `examples/
|
781
|
+
Run `examples/builder/identity.rb`:
|
782
782
|
```sh
|
783
783
|
% ruby examples/builder/identity.rb
|
784
784
|
#<struct CallableTree::Node::External::Output
|
@@ -12,7 +12,7 @@ JSONParser =
|
|
12
12
|
end
|
13
13
|
.caller do |input, **options, &block|
|
14
14
|
File.open(input) do |file|
|
15
|
-
json =
|
15
|
+
json = JSON.load(file)
|
16
16
|
# The following block call is equivalent to calling `super` in the class style.
|
17
17
|
block.call(json, **options)
|
18
18
|
end
|
@@ -12,7 +12,7 @@ JSONParser =
|
|
12
12
|
end
|
13
13
|
.caller do |input, **options, &block|
|
14
14
|
File.open(input) do |file|
|
15
|
-
json =
|
15
|
+
json = JSON.load(file)
|
16
16
|
# The following block call is equivalent to calling `super` in the class style.
|
17
17
|
block.call(json, **options)
|
18
18
|
end
|
@@ -12,7 +12,7 @@ JSONParser =
|
|
12
12
|
end
|
13
13
|
.caller do |input, **options, &original|
|
14
14
|
File.open(input) do |file|
|
15
|
-
json =
|
15
|
+
json = JSON.load(file)
|
16
16
|
# The following block call is equivalent to calling `super` in the class style.
|
17
17
|
original.call(json, **options)
|
18
18
|
end
|
data/examples/builder/logging.rb
CHANGED
@@ -12,7 +12,7 @@ JSONParser =
|
|
12
12
|
end
|
13
13
|
.caller do |input, **options, &original|
|
14
14
|
File.open(input) do |file|
|
15
|
-
json =
|
15
|
+
json = JSON.load(file)
|
16
16
|
# The following block call is equivalent to calling `super` in the class style.
|
17
17
|
original.call(json, **options)
|
18
18
|
end
|
@@ -87,19 +87,19 @@ module Logging
|
|
87
87
|
matched
|
88
88
|
end
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
90
|
+
return unless node.external?
|
91
|
+
|
92
|
+
node
|
93
|
+
.before_caller! do |input, *, _node_:, **|
|
94
|
+
input_prefix = INPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + INPUT_LABEL.length, BLANK)
|
95
|
+
puts "#{input_prefix} #{input}"
|
96
|
+
input
|
97
|
+
end
|
98
|
+
.after_caller! do |output, _node_:, **|
|
99
|
+
output_prefix = OUTPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + OUTPUT_LABEL.length, BLANK)
|
100
|
+
puts "#{output_prefix} #{output}"
|
101
|
+
output
|
102
|
+
end
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
data/examples/class/logging.rb
CHANGED
@@ -124,19 +124,19 @@ module Logging
|
|
124
124
|
matched
|
125
125
|
end
|
126
126
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
127
|
+
return unless node.external?
|
128
|
+
|
129
|
+
node
|
130
|
+
.before_caller! do |input, *, _node_:, **|
|
131
|
+
input_prefix = INPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + INPUT_LABEL.length, BLANK)
|
132
|
+
puts "#{input_prefix} #{input}"
|
133
|
+
input
|
134
|
+
end
|
135
|
+
.after_caller! do |output, _node_:, **|
|
136
|
+
output_prefix = OUTPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + OUTPUT_LABEL.length, BLANK)
|
137
|
+
puts "#{output_prefix} #{output}"
|
138
|
+
output
|
139
|
+
end
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
@@ -6,10 +6,10 @@ module CallableTree
|
|
6
6
|
include Node
|
7
7
|
|
8
8
|
def self.included(mod)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
return unless mod.include?(Internal)
|
10
|
+
|
11
|
+
raise ::CallableTree::Error,
|
12
|
+
"#{mod} cannot include #{self} together with #{Internal}"
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.proxify(callable)
|
@@ -7,26 +7,19 @@ module CallableTree
|
|
7
7
|
class Broadcast
|
8
8
|
include Strategy
|
9
9
|
|
10
|
-
def initialize(terminable: false)
|
10
|
+
def initialize(matchable: true, terminable: false)
|
11
|
+
self.matchable = matchable
|
11
12
|
self.terminable = terminable
|
12
|
-
@terminator =
|
13
|
-
if terminable
|
14
|
-
proc { |node, output, *inputs, **options| node.terminate?(output, *inputs, **options) }
|
15
|
-
else
|
16
|
-
proc { false }
|
17
|
-
end
|
18
13
|
end
|
19
14
|
|
20
15
|
def call(nodes, *inputs, **options)
|
21
|
-
nodes.
|
22
|
-
output = (node.call(*inputs, **options) if
|
16
|
+
nodes.each_with_object([]) do |node, outputs|
|
17
|
+
output = (node.call(*inputs, **options) if matcher.call(node, *inputs, **options))
|
23
18
|
outputs << output
|
24
19
|
|
25
|
-
if
|
26
|
-
|
27
|
-
|
28
|
-
outputs
|
29
|
-
end
|
20
|
+
break outputs if terminator.call(node, output, *inputs, **options)
|
21
|
+
|
22
|
+
outputs
|
30
23
|
end
|
31
24
|
end
|
32
25
|
end
|
@@ -7,22 +7,17 @@ module CallableTree
|
|
7
7
|
class Compose
|
8
8
|
include Strategy
|
9
9
|
|
10
|
-
def initialize(terminable: false)
|
10
|
+
def initialize(matchable: true, terminable: false)
|
11
|
+
self.matchable = matchable
|
11
12
|
self.terminable = terminable
|
12
|
-
@terminator =
|
13
|
-
if terminable
|
14
|
-
proc { |node, output, *inputs, **options| node.terminate?(output, *inputs, **options) }
|
15
|
-
else
|
16
|
-
proc { false }
|
17
|
-
end
|
18
13
|
end
|
19
14
|
|
20
15
|
def call(nodes, *inputs, **options)
|
21
16
|
head, *tail = inputs
|
22
17
|
nodes.reduce(head) do |input, node|
|
23
|
-
if
|
18
|
+
if matcher.call(node, input, *tail, **options)
|
24
19
|
output = node.call(input, *tail, **options)
|
25
|
-
break output if
|
20
|
+
break output if terminator.call(node, output, input, *tail, **options)
|
26
21
|
|
27
22
|
output
|
28
23
|
else
|
@@ -7,23 +7,18 @@ module CallableTree
|
|
7
7
|
class Seek
|
8
8
|
include Strategy
|
9
9
|
|
10
|
-
def initialize(terminable: true)
|
10
|
+
def initialize(matchable: true, terminable: true)
|
11
|
+
self.matchable = matchable
|
11
12
|
self.terminable = terminable
|
12
|
-
@terminator =
|
13
|
-
if terminable
|
14
|
-
proc { |node, output, *inputs, **options| node.terminate?(output, *inputs, **options) }
|
15
|
-
else
|
16
|
-
proc { false }
|
17
|
-
end
|
18
13
|
end
|
19
14
|
|
20
15
|
def call(nodes, *inputs, **options)
|
21
16
|
nodes
|
22
17
|
.lazy
|
23
|
-
.select { |node|
|
18
|
+
.select { |node| matcher.call(node, *inputs, **options) }
|
24
19
|
.map do |node|
|
25
20
|
output = node.call(*inputs, **options)
|
26
|
-
terminated =
|
21
|
+
terminated = terminator.call(node, output, *inputs, **options)
|
27
22
|
[output, terminated]
|
28
23
|
end
|
29
24
|
.select { |_output, terminated| terminated }
|
@@ -13,7 +13,7 @@ module CallableTree
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def ==(other)
|
16
|
-
name == other.name && terminable? == other.terminable?
|
16
|
+
name == other.name && matchable? == other.matchable? && terminable? == other.terminable?
|
17
17
|
end
|
18
18
|
|
19
19
|
def eql?(other)
|
@@ -21,7 +21,11 @@ module CallableTree
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def hash
|
24
|
-
[self.class.name, terminable].join('-').hash
|
24
|
+
[self.class.name, matchable, terminable].join('-').hash
|
25
|
+
end
|
26
|
+
|
27
|
+
def matchable?
|
28
|
+
matchable
|
25
29
|
end
|
26
30
|
|
27
31
|
def terminable?
|
@@ -30,7 +34,25 @@ module CallableTree
|
|
30
34
|
|
31
35
|
private
|
32
36
|
|
33
|
-
attr_accessor :terminable
|
37
|
+
attr_accessor :matchable, :terminable
|
38
|
+
|
39
|
+
def matcher
|
40
|
+
@matcher ||=
|
41
|
+
if matchable
|
42
|
+
proc { |node, *inputs, **options| node.match?(*inputs, **options) }
|
43
|
+
else
|
44
|
+
proc { false }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def terminator
|
49
|
+
@terminator ||=
|
50
|
+
if terminable
|
51
|
+
proc { |node, output, *inputs, **options| node.terminate?(output, *inputs, **options) }
|
52
|
+
else
|
53
|
+
proc { false }
|
54
|
+
end
|
55
|
+
end
|
34
56
|
end
|
35
57
|
end
|
36
58
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CallableTree
|
4
|
+
module Node
|
5
|
+
module Internal
|
6
|
+
module Strategyable
|
7
|
+
def self.included(mod)
|
8
|
+
mod.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
DEFAUTL_FACTORY = proc do |klass, *_args, matchable:, terminable:, **_kwargs|
|
12
|
+
klass.new(matchable: matchable, terminable: terminable)
|
13
|
+
end
|
14
|
+
|
15
|
+
@@strategy_configs = {
|
16
|
+
seek: {
|
17
|
+
klass: Strategy::Seek,
|
18
|
+
alias: :seekable,
|
19
|
+
matchable: true,
|
20
|
+
terminable: true,
|
21
|
+
factory: DEFAUTL_FACTORY
|
22
|
+
},
|
23
|
+
broadcast: {
|
24
|
+
klass: Strategy::Broadcast,
|
25
|
+
alias: :broadcastable,
|
26
|
+
matchable: true,
|
27
|
+
terminable: false,
|
28
|
+
factory: DEFAUTL_FACTORY
|
29
|
+
},
|
30
|
+
compose: {
|
31
|
+
klass: Strategy::Compose,
|
32
|
+
alias: :composable,
|
33
|
+
matchable: true,
|
34
|
+
terminable: false,
|
35
|
+
factory: DEFAUTL_FACTORY
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
class << self
|
40
|
+
private
|
41
|
+
|
42
|
+
def strategy_configs
|
43
|
+
@@strategy_configs
|
44
|
+
end
|
45
|
+
|
46
|
+
def define_strategy_methods(key, config)
|
47
|
+
define_method(:"#{config[:alias]}?") { strategy.is_a?(config[:klass]) }
|
48
|
+
|
49
|
+
define_method(config[:alias]) do |*args, matchable: config[:matchable], terminable: config[:terminable], **kwargs|
|
50
|
+
# TODO: Modify to use strategize method
|
51
|
+
if strategy == config[:factory].call(
|
52
|
+
config[:klass], *args, matchable: matchable, terminable: terminable, **kwargs
|
53
|
+
)
|
54
|
+
self
|
55
|
+
else
|
56
|
+
clone.__send__(:"#{config[:alias]}!", *args, matchable: matchable, terminable: terminable, **kwargs)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
define_method(:"#{config[:alias]}!") do |*args, matchable: config[:matchable], terminable: config[:terminable], **kwargs|
|
61
|
+
strategize!(key, *args, matchable: matchable, terminable: terminable, **kwargs)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
module ClassMethods
|
67
|
+
def store_strategy(key, config)
|
68
|
+
raise ::CallableTree::Error, 'Strategy class is required. [:klass]' unless config[:klass]
|
69
|
+
|
70
|
+
key = key.to_sym
|
71
|
+
config[:alias] = key unless config[:alias]
|
72
|
+
config[:factory] = DEFAUTL_FACTORY unless config[:factory]
|
73
|
+
Strategyable.__send__(:strategy_configs)[key] = config
|
74
|
+
Strategyable.__send__(:define_strategy_methods, key, config)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
@@strategy_configs.each { |key, config| define_strategy_methods(key, config) }
|
79
|
+
|
80
|
+
# Backward compatibility
|
81
|
+
alias seek? seekable?
|
82
|
+
alias seek seekable
|
83
|
+
alias seek! seekable!
|
84
|
+
alias broadcast? broadcastable?
|
85
|
+
alias broadcast broadcastable
|
86
|
+
alias broadcast! broadcastable!
|
87
|
+
alias compose? composable?
|
88
|
+
alias compose composable
|
89
|
+
alias compose! composable!
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
attr_writer :strategy
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def strategize(name, *args, matchable:, terminable:, **kwargs)
|
98
|
+
clone.strategy!(name, *args, matchable: matchable, terminable: terminable, **kwargs)
|
99
|
+
end
|
100
|
+
|
101
|
+
def strategize!(name, *args, matchable:, terminable:, **kwargs)
|
102
|
+
config = @@strategy_configs[name.to_sym]
|
103
|
+
raise ::CallableTree::Error, "Strategy is not found. [#{name}]" unless config
|
104
|
+
|
105
|
+
self.strategy = config[:factory].call(
|
106
|
+
config[:klass], *args, matchable: matchable, terminable: terminable, **kwargs
|
107
|
+
)
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
def strategy
|
112
|
+
@strategy ||= @@strategy_configs[:seek][:klass].new
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -5,12 +5,13 @@ module CallableTree
|
|
5
5
|
module Internal
|
6
6
|
extend ::Forwardable
|
7
7
|
include Node
|
8
|
+
include Strategyable
|
8
9
|
|
9
10
|
def self.included(mod)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
return unless mod.include?(External)
|
12
|
+
|
13
|
+
raise ::CallableTree::Error,
|
14
|
+
"#{mod} cannot include #{self} together with #{External}"
|
14
15
|
end
|
15
16
|
|
16
17
|
def_delegators :child_nodes, :[], :at
|
@@ -39,14 +40,14 @@ module CallableTree
|
|
39
40
|
node = child_nodes.find(&block)
|
40
41
|
return node if node
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
return unless recursive
|
44
|
+
|
45
|
+
child_nodes
|
46
|
+
.lazy
|
47
|
+
.select(&:internal?)
|
48
|
+
.map { |node| node.find(recursive: true, &block) }
|
49
|
+
.reject(&:nil?)
|
50
|
+
.first
|
50
51
|
end
|
51
52
|
|
52
53
|
def reject(recursive: false, &block)
|
@@ -85,72 +86,6 @@ module CallableTree
|
|
85
86
|
strategy.call(child_nodes, *inputs, **options)
|
86
87
|
end
|
87
88
|
|
88
|
-
def seek?
|
89
|
-
strategy.is_a?(Strategy::Seek)
|
90
|
-
end
|
91
|
-
|
92
|
-
def seek(terminable: true)
|
93
|
-
if strategy == Strategy::Seek.new(terminable: terminable)
|
94
|
-
self
|
95
|
-
else
|
96
|
-
clone.seek!(terminable: terminable)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def seek!(terminable: true)
|
101
|
-
self.strategy = Strategy::Seek.new(terminable: terminable)
|
102
|
-
|
103
|
-
self
|
104
|
-
end
|
105
|
-
|
106
|
-
alias seekable? seek?
|
107
|
-
alias seekable seek
|
108
|
-
alias seekable! seek!
|
109
|
-
|
110
|
-
def broadcast?
|
111
|
-
strategy.is_a?(Strategy::Broadcast)
|
112
|
-
end
|
113
|
-
|
114
|
-
def broadcast(terminable: false)
|
115
|
-
if strategy == Strategy::Broadcast.new(terminable: terminable)
|
116
|
-
self
|
117
|
-
else
|
118
|
-
clone.broadcast!(terminable: terminable)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def broadcast!(terminable: false)
|
123
|
-
self.strategy = Strategy::Broadcast.new(terminable: terminable)
|
124
|
-
|
125
|
-
self
|
126
|
-
end
|
127
|
-
|
128
|
-
alias broadcastable? broadcast?
|
129
|
-
alias broadcastable broadcast
|
130
|
-
alias broadcastable! broadcast!
|
131
|
-
|
132
|
-
def compose?
|
133
|
-
strategy.is_a?(Strategy::Compose)
|
134
|
-
end
|
135
|
-
|
136
|
-
def compose(terminable: false)
|
137
|
-
if strategy == Strategy::Compose.new(terminable: terminable)
|
138
|
-
self
|
139
|
-
else
|
140
|
-
clone.compose!(terminable: terminable)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def compose!(terminable: false)
|
145
|
-
self.strategy = Strategy::Compose.new(terminable: terminable)
|
146
|
-
|
147
|
-
self
|
148
|
-
end
|
149
|
-
|
150
|
-
alias composable? compose?
|
151
|
-
alias composable compose
|
152
|
-
alias composable! compose!
|
153
|
-
|
154
89
|
def outline(&block)
|
155
90
|
key = block ? block.call(self) : identity
|
156
91
|
value = child_nodes.reduce({}) { |memo, node| memo.merge!(node.outline(&block)) }
|
@@ -165,10 +100,6 @@ module CallableTree
|
|
165
100
|
false
|
166
101
|
end
|
167
102
|
|
168
|
-
protected
|
169
|
-
|
170
|
-
attr_writer :strategy
|
171
|
-
|
172
103
|
def child_nodes
|
173
104
|
@child_nodes ||= []
|
174
105
|
end
|
@@ -186,10 +117,6 @@ module CallableTree
|
|
186
117
|
.tap { |node| node.parent = self }
|
187
118
|
end
|
188
119
|
|
189
|
-
def strategy
|
190
|
-
@strategy ||= Strategy::Seek.new
|
191
|
-
end
|
192
|
-
|
193
120
|
def initialize_copy(_node)
|
194
121
|
super
|
195
122
|
self.parent = nil
|
data/lib/callable_tree/node.rb
CHANGED
data/lib/callable_tree.rb
CHANGED
@@ -14,6 +14,7 @@ require_relative 'callable_tree/node/internal/strategy'
|
|
14
14
|
require_relative 'callable_tree/node/internal/strategy/broadcast'
|
15
15
|
require_relative 'callable_tree/node/internal/strategy/seek'
|
16
16
|
require_relative 'callable_tree/node/internal/strategy/compose'
|
17
|
+
require_relative 'callable_tree/node/internal/strategyable'
|
17
18
|
require_relative 'callable_tree/node/external/verbose'
|
18
19
|
require_relative 'callable_tree/node/external'
|
19
20
|
require_relative 'callable_tree/node/internal'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: callable_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jsmmr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Builds a tree by linking callable nodes. The nodes that match the conditions
|
14
14
|
are called in a chain from the root node to the leaf node. These are like nested
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/callable_tree/node/internal/strategy/broadcast.rb
|
69
69
|
- lib/callable_tree/node/internal/strategy/compose.rb
|
70
70
|
- lib/callable_tree/node/internal/strategy/seek.rb
|
71
|
+
- lib/callable_tree/node/internal/strategyable.rb
|
71
72
|
- lib/callable_tree/node/root.rb
|
72
73
|
- lib/callable_tree/version.rb
|
73
74
|
homepage: https://github.com/jsmmr/ruby_callable_tree
|
@@ -76,7 +77,7 @@ licenses:
|
|
76
77
|
metadata:
|
77
78
|
homepage_uri: https://github.com/jsmmr/ruby_callable_tree
|
78
79
|
source_code_uri: https://github.com/jsmmr/ruby_callable_tree
|
79
|
-
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.
|
80
|
+
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.10/CHANGELOG.md
|
80
81
|
rubygems_mfa_required: 'true'
|
81
82
|
post_install_message:
|
82
83
|
rdoc_options: []
|
@@ -93,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
94
|
- !ruby/object:Gem::Version
|
94
95
|
version: '0'
|
95
96
|
requirements: []
|
96
|
-
rubygems_version: 3.
|
97
|
+
rubygems_version: 3.4.1
|
97
98
|
signing_key:
|
98
99
|
specification_version: 4
|
99
100
|
summary: Builds a tree by linking callable nodes. The nodes that match the conditions
|