callable_tree 0.3.7 → 0.3.9
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/dependabot.yml +7 -0
- data/.github/workflows/build.yml +3 -5
- data/.github/workflows/codeql-analysis.yml +4 -4
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +3 -3
- data/README.md +460 -276
- data/callable_tree.gemspec +1 -0
- data/examples/builder/external-verbosify.rb +87 -0
- data/examples/builder/hooks.rb +67 -0
- data/examples/builder/identity.rb +91 -0
- data/examples/builder/internal-broadcastable.rb +11 -11
- data/examples/builder/internal-composable.rb +11 -11
- data/examples/builder/internal-seekable.rb +9 -15
- data/examples/builder/logging.rb +36 -39
- data/examples/{external-verbosify.rb → class/external-verbosify.rb} +3 -5
- data/examples/class/hooks.rb +70 -0
- data/examples/{identity.rb → class/identity.rb} +3 -5
- data/examples/{internal-broadcastable.rb → class/internal-broadcastable.rb} +0 -0
- data/examples/{internal-composable.rb → class/internal-composable.rb} +0 -0
- data/examples/{internal-seekable.rb → class/internal-seekable.rb} +3 -5
- data/examples/{logging.rb → class/logging.rb} +47 -47
- data/lib/callable_tree/node/builder.rb +13 -0
- data/lib/callable_tree/node/hooks/terminator.rb +99 -0
- data/lib/callable_tree/node/internal/strategy/broadcast.rb +19 -2
- data/lib/callable_tree/node/internal/strategy/compose.rb +15 -3
- data/lib/callable_tree/node/internal/strategy/seek.rb +11 -1
- data/lib/callable_tree/node/internal/strategy.rb +10 -2
- data/lib/callable_tree/node/internal.rb +22 -28
- data/lib/callable_tree/node/root.rb +1 -0
- data/lib/callable_tree/version.rb +1 -1
- data/lib/callable_tree.rb +1 -0
- metadata +17 -11
- data/examples/builder/hooks-caller.rb +0 -38
- data/examples/hooks-caller.rb +0 -39
@@ -55,8 +55,7 @@ module Node
|
|
55
55
|
|
56
56
|
def call(input, **_options)
|
57
57
|
input[@type.to_s]
|
58
|
-
.
|
59
|
-
.to_h
|
58
|
+
.to_h { |element| [element['name'], element['emoji']] }
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
@@ -99,8 +98,7 @@ module Node
|
|
99
98
|
input
|
100
99
|
.get_elements("//#{@type}")
|
101
100
|
.first
|
102
|
-
.
|
103
|
-
.to_h
|
101
|
+
.to_h { |element| [element['name'], element['emoji']] }
|
104
102
|
end
|
105
103
|
end
|
106
104
|
end
|
@@ -117,7 +115,7 @@ tree = CallableTree::Node::Root.new.append(
|
|
117
115
|
)
|
118
116
|
)
|
119
117
|
|
120
|
-
Dir.glob("#{__dir__}
|
118
|
+
Dir.glob("#{__dir__}/../docs/*") do |file|
|
121
119
|
options = { foo: :bar }
|
122
120
|
pp tree.call(file, **options)
|
123
121
|
puts '---'
|
File without changes
|
File without changes
|
@@ -38,8 +38,7 @@ module Node
|
|
38
38
|
|
39
39
|
def call(input, **_options)
|
40
40
|
input[@type.to_s]
|
41
|
-
.
|
42
|
-
.to_h
|
41
|
+
.to_h { |element| [element['name'], element['emoji']] }
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
@@ -78,8 +77,7 @@ module Node
|
|
78
77
|
input
|
79
78
|
.get_elements("//#{@type}")
|
80
79
|
.first
|
81
|
-
.
|
82
|
-
.to_h
|
80
|
+
.to_h { |element| [element['name'], element['emoji']] }
|
83
81
|
end
|
84
82
|
end
|
85
83
|
end
|
@@ -96,7 +94,7 @@ tree = CallableTree::Node::Root.new.seekable.append(
|
|
96
94
|
)
|
97
95
|
)
|
98
96
|
|
99
|
-
Dir.glob("#{__dir__}
|
97
|
+
Dir.glob("#{__dir__}/../docs/*") do |file|
|
100
98
|
options = { foo: :bar }
|
101
99
|
pp tree.call(file, **options)
|
102
100
|
puts '---'
|
@@ -5,36 +5,6 @@ require 'json'
|
|
5
5
|
require 'rexml/document'
|
6
6
|
|
7
7
|
module Node
|
8
|
-
module Logging
|
9
|
-
INDENT_SIZE = 2
|
10
|
-
BLANK = ' '
|
11
|
-
|
12
|
-
module Match
|
13
|
-
LIST_STYLE = '*'
|
14
|
-
|
15
|
-
def match?(_input, **_options)
|
16
|
-
super.tap do |matched|
|
17
|
-
prefix = LIST_STYLE.rjust(depth * INDENT_SIZE - INDENT_SIZE + LIST_STYLE.length, BLANK)
|
18
|
-
puts "#{prefix} #{identity}: [matched: #{matched}]"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
module Call
|
24
|
-
INPUT_LABEL = 'Input :'
|
25
|
-
OUTPUT_LABEL = 'Output:'
|
26
|
-
|
27
|
-
def call(input, **_options)
|
28
|
-
super.tap do |output|
|
29
|
-
input_prefix = INPUT_LABEL.rjust(depth * INDENT_SIZE + INPUT_LABEL.length, BLANK)
|
30
|
-
puts "#{input_prefix} #{input}"
|
31
|
-
output_prefix = OUTPUT_LABEL.rjust(depth * INDENT_SIZE + OUTPUT_LABEL.length, BLANK)
|
32
|
-
puts "#{output_prefix} #{output}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
8
|
class Identity
|
39
9
|
attr_reader :klass, :type
|
40
10
|
|
@@ -51,7 +21,7 @@ module Node
|
|
51
21
|
module JSON
|
52
22
|
class Parser
|
53
23
|
include CallableTree::Node::Internal
|
54
|
-
prepend
|
24
|
+
prepend CallableTree::Node::Hooks::Matcher
|
55
25
|
|
56
26
|
def match?(input, **_options)
|
57
27
|
File.extname(input) == '.json'
|
@@ -71,8 +41,8 @@ module Node
|
|
71
41
|
|
72
42
|
class Scraper
|
73
43
|
include CallableTree::Node::External
|
74
|
-
prepend
|
75
|
-
prepend
|
44
|
+
prepend CallableTree::Node::Hooks::Matcher
|
45
|
+
prepend CallableTree::Node::Hooks::Caller
|
76
46
|
|
77
47
|
def initialize(type:)
|
78
48
|
@type = type
|
@@ -88,8 +58,7 @@ module Node
|
|
88
58
|
|
89
59
|
def call(input, **_options)
|
90
60
|
input[@type.to_s]
|
91
|
-
.
|
92
|
-
.to_h
|
61
|
+
.to_h { |element| [element['name'], element['emoji']] }
|
93
62
|
end
|
94
63
|
end
|
95
64
|
end
|
@@ -97,7 +66,7 @@ module Node
|
|
97
66
|
module XML
|
98
67
|
class Parser
|
99
68
|
include CallableTree::Node::Internal
|
100
|
-
prepend
|
69
|
+
prepend CallableTree::Node::Hooks::Matcher
|
101
70
|
|
102
71
|
def match?(input, **_options)
|
103
72
|
File.extname(input) == '.xml'
|
@@ -116,8 +85,8 @@ module Node
|
|
116
85
|
|
117
86
|
class Scraper
|
118
87
|
include CallableTree::Node::External
|
119
|
-
prepend
|
120
|
-
prepend
|
88
|
+
prepend CallableTree::Node::Hooks::Matcher
|
89
|
+
prepend CallableTree::Node::Hooks::Caller
|
121
90
|
|
122
91
|
def initialize(type:)
|
123
92
|
@type = type
|
@@ -135,25 +104,56 @@ module Node
|
|
135
104
|
input
|
136
105
|
.get_elements("//#{@type}")
|
137
106
|
.first
|
138
|
-
.
|
139
|
-
.to_h
|
107
|
+
.to_h { |element| [element['name'], element['emoji']] }
|
140
108
|
end
|
141
109
|
end
|
142
110
|
end
|
143
111
|
end
|
144
112
|
|
113
|
+
module Logging
|
114
|
+
INDENT_SIZE = 2
|
115
|
+
BLANK = ' '
|
116
|
+
LIST_STYLE = '*'
|
117
|
+
INPUT_LABEL = 'Input :'
|
118
|
+
OUTPUT_LABEL = 'Output:'
|
119
|
+
|
120
|
+
def self.loggable(node)
|
121
|
+
node.after_matcher! do |matched, _node_:, **|
|
122
|
+
prefix = LIST_STYLE.rjust((_node_.depth * INDENT_SIZE) - INDENT_SIZE + LIST_STYLE.length, BLANK)
|
123
|
+
puts "#{prefix} #{_node_.identity}: [matched: #{matched}]"
|
124
|
+
matched
|
125
|
+
end
|
126
|
+
|
127
|
+
if node.external?
|
128
|
+
node
|
129
|
+
.before_caller! do |input, *, _node_:, **|
|
130
|
+
input_prefix = INPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + INPUT_LABEL.length, BLANK)
|
131
|
+
puts "#{input_prefix} #{input}"
|
132
|
+
input
|
133
|
+
end
|
134
|
+
.after_caller! do |output, _node_:, **|
|
135
|
+
output_prefix = OUTPUT_LABEL.rjust((_node_.depth * INDENT_SIZE) + OUTPUT_LABEL.length, BLANK)
|
136
|
+
puts "#{output_prefix} #{output}"
|
137
|
+
output
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
loggable = Logging.method(:loggable)
|
144
|
+
|
145
145
|
tree = CallableTree::Node::Root.new.append(
|
146
|
-
Node::JSON::Parser.new.append(
|
147
|
-
Node::JSON::Scraper.new(type: :animals).verbosify,
|
148
|
-
Node::JSON::Scraper.new(type: :fruits).verbosify
|
146
|
+
Node::JSON::Parser.new.tap(&loggable).append(
|
147
|
+
Node::JSON::Scraper.new(type: :animals).tap(&loggable).verbosify,
|
148
|
+
Node::JSON::Scraper.new(type: :fruits).tap(&loggable).verbosify
|
149
149
|
),
|
150
|
-
Node::XML::Parser.new.append(
|
151
|
-
Node::XML::Scraper.new(type: :animals).verbosify,
|
152
|
-
Node::XML::Scraper.new(type: :fruits).verbosify
|
150
|
+
Node::XML::Parser.new.tap(&loggable).append(
|
151
|
+
Node::XML::Scraper.new(type: :animals).tap(&loggable).verbosify,
|
152
|
+
Node::XML::Scraper.new(type: :fruits).tap(&loggable).verbosify
|
153
153
|
)
|
154
154
|
)
|
155
155
|
|
156
|
-
Dir.glob("#{__dir__}
|
156
|
+
Dir.glob("#{__dir__}/../docs/*") do |file|
|
157
157
|
options = { foo: :bar }
|
158
158
|
pp tree.call(file, **options)
|
159
159
|
puts '---'
|
@@ -24,6 +24,11 @@ module CallableTree
|
|
24
24
|
self
|
25
25
|
end
|
26
26
|
|
27
|
+
def identifier(&block)
|
28
|
+
@identifier = block
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
27
32
|
def hookable(hookable = true)
|
28
33
|
@hookable = hookable
|
29
34
|
self
|
@@ -33,6 +38,7 @@ module CallableTree
|
|
33
38
|
matcher = @matcher
|
34
39
|
caller = @caller
|
35
40
|
terminator = @terminator
|
41
|
+
identifier = @identifier
|
36
42
|
hookable = @hookable
|
37
43
|
|
38
44
|
validate(
|
@@ -47,6 +53,7 @@ module CallableTree
|
|
47
53
|
if hookable
|
48
54
|
prepend Hooks::Matcher
|
49
55
|
prepend Hooks::Caller
|
56
|
+
prepend Hooks::Terminator
|
50
57
|
end
|
51
58
|
|
52
59
|
if matcher
|
@@ -72,6 +79,12 @@ module CallableTree
|
|
72
79
|
end
|
73
80
|
end
|
74
81
|
end
|
82
|
+
|
83
|
+
if identifier
|
84
|
+
define_method(:identity) do
|
85
|
+
identifier.call(_node_: self) { super() }
|
86
|
+
end
|
87
|
+
end
|
75
88
|
end
|
76
89
|
end
|
77
90
|
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CallableTree
|
4
|
+
module Node
|
5
|
+
module Hooks
|
6
|
+
module Terminator
|
7
|
+
def self.included(_subclass)
|
8
|
+
raise ::CallableTree::Error, "#{self} must be prepended"
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_terminator(&block)
|
12
|
+
clone.before_terminator!(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_terminator!(&block)
|
16
|
+
before_terminator_callbacks << block
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def around_terminator(&block)
|
21
|
+
clone.around_terminator!(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def around_terminator!(&block)
|
25
|
+
around_terminator_callbacks << block
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_terminator(&block)
|
30
|
+
clone.after_terminator!(&block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_terminator!(&block)
|
34
|
+
after_terminator_callbacks << block
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def terminate?(output, *inputs, **options)
|
39
|
+
output = before_terminator_callbacks.reduce(output) do |output, callable|
|
40
|
+
callable.call(output, *inputs, **options, _node_: self)
|
41
|
+
end
|
42
|
+
|
43
|
+
terminated =
|
44
|
+
if around_terminator_callbacks.empty?
|
45
|
+
super(output, *inputs, **options)
|
46
|
+
else
|
47
|
+
around_terminator_callbacks_head, *around_terminator_callbacks_tail = around_terminator_callbacks
|
48
|
+
terminator = proc { super(output, *inputs, **options) }
|
49
|
+
|
50
|
+
terminated =
|
51
|
+
around_terminator_callbacks_head
|
52
|
+
.call(
|
53
|
+
output,
|
54
|
+
*inputs,
|
55
|
+
**options,
|
56
|
+
_node_: self
|
57
|
+
) { terminator.call }
|
58
|
+
|
59
|
+
around_terminator_callbacks_tail.reduce(terminated) do |terminated, callable|
|
60
|
+
callable.call(
|
61
|
+
output,
|
62
|
+
*inputs,
|
63
|
+
**options,
|
64
|
+
_node_: self
|
65
|
+
) { terminated }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
after_terminator_callbacks.reduce(terminated) do |terminated, callable|
|
70
|
+
callable.call(terminated, **options, _node_: self)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def before_terminator_callbacks
|
75
|
+
@before_terminator_callbacks ||= []
|
76
|
+
end
|
77
|
+
|
78
|
+
def around_terminator_callbacks
|
79
|
+
@around_terminator_callbacks ||= []
|
80
|
+
end
|
81
|
+
|
82
|
+
def after_terminator_callbacks
|
83
|
+
@after_terminator_callbacks ||= []
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
attr_writer :before_terminator_callbacks, :around_terminator_callbacks, :after_terminator_callbacks
|
89
|
+
|
90
|
+
def initialize_copy(_node)
|
91
|
+
super
|
92
|
+
self.before_terminator_callbacks = before_terminator_callbacks.map(&:itself)
|
93
|
+
self.around_terminator_callbacks = around_terminator_callbacks.map(&:itself)
|
94
|
+
self.after_terminator_callbacks = after_terminator_callbacks.map(&:itself)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -7,9 +7,26 @@ module CallableTree
|
|
7
7
|
class Broadcast
|
8
8
|
include Strategy
|
9
9
|
|
10
|
+
def initialize(terminable: false)
|
11
|
+
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
|
+
end
|
19
|
+
|
10
20
|
def call(nodes, *inputs, **options)
|
11
|
-
nodes.
|
12
|
-
node.call(*inputs, **options) if node.match?(*inputs, **options)
|
21
|
+
nodes.reduce([]) do |outputs, node|
|
22
|
+
output = (node.call(*inputs, **options) if node.match?(*inputs, **options))
|
23
|
+
outputs << output
|
24
|
+
|
25
|
+
if @terminator.call(node, output, *inputs, **options)
|
26
|
+
break outputs
|
27
|
+
else
|
28
|
+
outputs
|
29
|
+
end
|
13
30
|
end
|
14
31
|
end
|
15
32
|
end
|
@@ -7,12 +7,24 @@ module CallableTree
|
|
7
7
|
class Compose
|
8
8
|
include Strategy
|
9
9
|
|
10
|
+
def initialize(terminable: false)
|
11
|
+
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
|
+
end
|
19
|
+
|
10
20
|
def call(nodes, *inputs, **options)
|
11
21
|
head, *tail = inputs
|
12
22
|
nodes.reduce(head) do |input, node|
|
13
|
-
|
14
|
-
|
15
|
-
|
23
|
+
if node.match?(input, *tail, **options)
|
24
|
+
output = node.call(input, *tail, **options)
|
25
|
+
break output if @terminator.call(node, output, input, *tail, **options)
|
26
|
+
|
27
|
+
output
|
16
28
|
else
|
17
29
|
input
|
18
30
|
end
|
@@ -7,13 +7,23 @@ module CallableTree
|
|
7
7
|
class Seek
|
8
8
|
include Strategy
|
9
9
|
|
10
|
+
def initialize(terminable: true)
|
11
|
+
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
|
+
end
|
19
|
+
|
10
20
|
def call(nodes, *inputs, **options)
|
11
21
|
nodes
|
12
22
|
.lazy
|
13
23
|
.select { |node| node.match?(*inputs, **options) }
|
14
24
|
.map do |node|
|
15
25
|
output = node.call(*inputs, **options)
|
16
|
-
terminated =
|
26
|
+
terminated = @terminator.call(node, output, *inputs, **options)
|
17
27
|
[output, terminated]
|
18
28
|
end
|
19
29
|
.select { |_output, terminated| terminated }
|
@@ -13,7 +13,7 @@ module CallableTree
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def ==(other)
|
16
|
-
name == other.name
|
16
|
+
name == other.name && terminable? == other.terminable?
|
17
17
|
end
|
18
18
|
|
19
19
|
def eql?(other)
|
@@ -21,8 +21,16 @@ module CallableTree
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def hash
|
24
|
-
self.class.name.hash
|
24
|
+
[self.class.name, terminable].join('-').hash
|
25
25
|
end
|
26
|
+
|
27
|
+
def terminable?
|
28
|
+
terminable
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_accessor :terminable
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -42,7 +42,7 @@ module CallableTree
|
|
42
42
|
if recursive
|
43
43
|
child_nodes
|
44
44
|
.lazy
|
45
|
-
.select
|
45
|
+
.select(&:internal?)
|
46
46
|
.map { |node| node.find(recursive: true, &block) }
|
47
47
|
.reject(&:nil?)
|
48
48
|
.first
|
@@ -89,20 +89,18 @@ module CallableTree
|
|
89
89
|
strategy.is_a?(Strategy::Seek)
|
90
90
|
end
|
91
91
|
|
92
|
-
def seek
|
93
|
-
if
|
92
|
+
def seek(terminable: true)
|
93
|
+
if strategy == Strategy::Seek.new(terminable: terminable)
|
94
94
|
self
|
95
95
|
else
|
96
|
-
clone.
|
97
|
-
node.strategy = Strategy::Seek.new
|
98
|
-
end
|
96
|
+
clone.seek!(terminable: terminable)
|
99
97
|
end
|
100
98
|
end
|
101
99
|
|
102
|
-
def seek!
|
103
|
-
|
104
|
-
|
105
|
-
|
100
|
+
def seek!(terminable: true)
|
101
|
+
self.strategy = Strategy::Seek.new(terminable: terminable)
|
102
|
+
|
103
|
+
self
|
106
104
|
end
|
107
105
|
|
108
106
|
alias seekable? seek?
|
@@ -113,20 +111,18 @@ module CallableTree
|
|
113
111
|
strategy.is_a?(Strategy::Broadcast)
|
114
112
|
end
|
115
113
|
|
116
|
-
def broadcast
|
117
|
-
if
|
114
|
+
def broadcast(terminable: false)
|
115
|
+
if strategy == Strategy::Broadcast.new(terminable: terminable)
|
118
116
|
self
|
119
117
|
else
|
120
|
-
clone.
|
121
|
-
node.strategy = Strategy::Broadcast.new
|
122
|
-
end
|
118
|
+
clone.broadcast!(terminable: terminable)
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
126
|
-
def broadcast!
|
127
|
-
|
128
|
-
|
129
|
-
|
122
|
+
def broadcast!(terminable: false)
|
123
|
+
self.strategy = Strategy::Broadcast.new(terminable: terminable)
|
124
|
+
|
125
|
+
self
|
130
126
|
end
|
131
127
|
|
132
128
|
alias broadcastable? broadcast?
|
@@ -137,20 +133,18 @@ module CallableTree
|
|
137
133
|
strategy.is_a?(Strategy::Compose)
|
138
134
|
end
|
139
135
|
|
140
|
-
def compose
|
141
|
-
if
|
136
|
+
def compose(terminable: false)
|
137
|
+
if strategy == Strategy::Compose.new(terminable: terminable)
|
142
138
|
self
|
143
139
|
else
|
144
|
-
clone.
|
145
|
-
node.strategy = Strategy::Compose.new
|
146
|
-
end
|
140
|
+
clone.compose!(terminable: terminable)
|
147
141
|
end
|
148
142
|
end
|
149
143
|
|
150
|
-
def compose!
|
151
|
-
|
152
|
-
|
153
|
-
|
144
|
+
def compose!(terminable: false)
|
145
|
+
self.strategy = Strategy::Compose.new(terminable: terminable)
|
146
|
+
|
147
|
+
self
|
154
148
|
end
|
155
149
|
|
156
150
|
alias composable? compose?
|
data/lib/callable_tree.rb
CHANGED
@@ -9,6 +9,7 @@ require_relative 'callable_tree/version'
|
|
9
9
|
require_relative 'callable_tree/node'
|
10
10
|
require_relative 'callable_tree/node/hooks/matcher'
|
11
11
|
require_relative 'callable_tree/node/hooks/caller'
|
12
|
+
require_relative 'callable_tree/node/hooks/terminator'
|
12
13
|
require_relative 'callable_tree/node/internal/strategy'
|
13
14
|
require_relative 'callable_tree/node/internal/strategy/broadcast'
|
14
15
|
require_relative 'callable_tree/node/internal/strategy/seek'
|
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.9
|
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-11-06 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
|
@@ -19,10 +19,12 @@ executables: []
|
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files: []
|
21
21
|
files:
|
22
|
+
- ".github/dependabot.yml"
|
22
23
|
- ".github/workflows/build.yml"
|
23
24
|
- ".github/workflows/codeql-analysis.yml"
|
24
25
|
- ".gitignore"
|
25
26
|
- ".rspec"
|
27
|
+
- ".rubocop.yml"
|
26
28
|
- ".ruby-version"
|
27
29
|
- CHANGELOG.md
|
28
30
|
- Gemfile
|
@@ -33,22 +35,24 @@ files:
|
|
33
35
|
- bin/console
|
34
36
|
- bin/setup
|
35
37
|
- callable_tree.gemspec
|
36
|
-
- examples/builder/
|
38
|
+
- examples/builder/external-verbosify.rb
|
39
|
+
- examples/builder/hooks.rb
|
40
|
+
- examples/builder/identity.rb
|
37
41
|
- examples/builder/internal-broadcastable.rb
|
38
42
|
- examples/builder/internal-composable.rb
|
39
43
|
- examples/builder/internal-seekable.rb
|
40
44
|
- examples/builder/logging.rb
|
45
|
+
- examples/class/external-verbosify.rb
|
46
|
+
- examples/class/hooks.rb
|
47
|
+
- examples/class/identity.rb
|
48
|
+
- examples/class/internal-broadcastable.rb
|
49
|
+
- examples/class/internal-composable.rb
|
50
|
+
- examples/class/internal-seekable.rb
|
51
|
+
- examples/class/logging.rb
|
41
52
|
- examples/docs/animals.json
|
42
53
|
- examples/docs/animals.xml
|
43
54
|
- examples/docs/fruits.json
|
44
55
|
- examples/docs/fruits.xml
|
45
|
-
- examples/external-verbosify.rb
|
46
|
-
- examples/hooks-caller.rb
|
47
|
-
- examples/identity.rb
|
48
|
-
- examples/internal-broadcastable.rb
|
49
|
-
- examples/internal-composable.rb
|
50
|
-
- examples/internal-seekable.rb
|
51
|
-
- examples/logging.rb
|
52
56
|
- lib/callable_tree.rb
|
53
57
|
- lib/callable_tree/node.rb
|
54
58
|
- lib/callable_tree/node/builder.rb
|
@@ -57,6 +61,7 @@ files:
|
|
57
61
|
- lib/callable_tree/node/external/verbose.rb
|
58
62
|
- lib/callable_tree/node/hooks/caller.rb
|
59
63
|
- lib/callable_tree/node/hooks/matcher.rb
|
64
|
+
- lib/callable_tree/node/hooks/terminator.rb
|
60
65
|
- lib/callable_tree/node/internal.rb
|
61
66
|
- lib/callable_tree/node/internal/builder.rb
|
62
67
|
- lib/callable_tree/node/internal/strategy.rb
|
@@ -71,7 +76,8 @@ licenses:
|
|
71
76
|
metadata:
|
72
77
|
homepage_uri: https://github.com/jsmmr/ruby_callable_tree
|
73
78
|
source_code_uri: https://github.com/jsmmr/ruby_callable_tree
|
74
|
-
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.
|
79
|
+
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.9/CHANGELOG.md
|
80
|
+
rubygems_mfa_required: 'true'
|
75
81
|
post_install_message:
|
76
82
|
rdoc_options: []
|
77
83
|
require_paths:
|