callable_tree 0.3.5 → 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: 83716fbdef2881db33e8f046f056a17d8a8866423951493902088bf1af53218f
4
- data.tar.gz: 8906217b71482e1717798329d172640a50f7cc73613a2187beba0702bf8b8d74
3
+ metadata.gz: 2a83d353d4049c06aa0a0d5f18f56c5c6d0d909cd4a54f6bbcba7faf4e835c0f
4
+ data.tar.gz: ab803f4e8b613a0ceb5e4d3ca21d38e1a5cf2a238db61384c0ec85b437fd7d73
5
5
  SHA512:
6
- metadata.gz: 5e5ece858eb3347c41ea5f573e37c972d1a127d9fa234cd2512b18ef9e882b33d0da900b46c8f8e539fcee36fccb6643d21bb0945169019e7734232907c412c1
7
- data.tar.gz: ce58af4b926c9201f4133f02da848dcfff7962f9fa08588c1d4b4b61765b9c5ffaf03f2cfb4367da7d14a80bc1dcd55ea4b53de39d4075be25ef6e2abaf9ae7e
6
+ metadata.gz: 27dd59b36d4ebc99395df901a900d72510928f5f4a9603405b83f54d0566652fda2253bcda7bf6efee1ad0363919c5ec7bb63a1ec1e0efc488e656d6ff1bce3a
7
+ data.tar.gz: 3029f92901053688715cffce367d0e44f01402743413dfd38dc52c6c63221094fe2d3774cf2b1b98d66b84dd6837c8d6e6430c228ce3f196e60f9222286a3a56
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
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
+
3
8
  ## [0.3.5] - 2022-03-20
4
9
 
5
10
  - Add `CallableTree::Node::Internal#seekable?` as an alias for `CallableTree::Node::Internal#seek?`.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- callable_tree (0.3.5)
4
+ callable_tree (0.3.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -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,14 +608,14 @@ 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
 
@@ -10,8 +10,8 @@ Root =
10
10
 
11
11
  Root
12
12
  .new
13
- .before_call do |input, **_options|
14
- puts "before_call input: #{input}"
13
+ .before_caller do |input, **_options|
14
+ puts "before_caller input: #{input}"
15
15
  input + 1
16
16
  end
17
17
  .append(
@@ -21,14 +21,14 @@ Root
21
21
  input * 2
22
22
  end
23
23
  )
24
- .around_call do |input, **_options, &block|
25
- puts "around_call input: #{input}"
24
+ .around_caller do |input, **_options, &block|
25
+ puts "around_caller input: #{input}"
26
26
  output = block.call
27
- puts "around_call output: #{output}"
27
+ puts "around_caller output: #{output}"
28
28
  output * input
29
29
  end
30
- .after_call do |output, **_options|
31
- puts "after_call output: #{output}"
30
+ .after_caller do |output, **_options|
31
+ puts "after_caller output: #{output}"
32
32
  output * 2
33
33
  end
34
34
  .tap do |tree|
@@ -4,89 +4,85 @@ require 'callable_tree'
4
4
  require 'json'
5
5
  require 'rexml/document'
6
6
 
7
- module JSONParser
8
- def self.build
9
- CallableTree::Node::Internal::Builder
10
- .new
11
- .matcher do |input, **_options|
12
- File.extname(input) == '.json'
13
- end
14
- .caller do |input, **options, &block|
15
- File.open(input) do |file|
16
- json = ::JSON.load(file)
17
- # The following block call is equivalent to calling `super` in the class style.
18
- block.call(json, **options)
19
- end
20
- end
21
- .terminator do
22
- true
23
- end
24
- .build
7
+ JSONParser =
8
+ CallableTree::Node::Internal::Builder
9
+ .new
10
+ .matcher do |input, **_options|
11
+ File.extname(input) == '.json'
25
12
  end
26
- end
27
-
28
- module XMLParser
29
- def self.build
30
- CallableTree::Node::Internal::Builder
31
- .new
32
- .matcher do |input, **_options|
33
- File.extname(input) == '.xml'
34
- end
35
- .caller do |input, **options, &block|
36
- File.open(input) do |file|
37
- # The following block call is equivalent to calling `super` in the class style.
38
- block.call(REXML::Document.new(file), **options)
39
- end
40
- end
41
- .terminator do
42
- true
43
- end
44
- .build
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
45
19
  end
46
- end
20
+ .terminator do
21
+ true
22
+ end
23
+ .build
47
24
 
48
- module JSONScraper
49
- def self.build(type)
50
- CallableTree::Node::External::Builder
51
- .new
52
- .matcher do |input, **_options|
53
- !!input[type.to_s]
54
- end
55
- .caller do |input, **_options|
56
- input[type.to_s]
57
- .map { |element| [element['name'], element['emoji']] }
58
- .to_h
59
- end
60
- .build
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
61
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
62
54
  end
63
55
 
64
- module XMLScraper
65
- def self.build(type)
66
- CallableTree::Node::External::Builder
67
- .new
68
- .matcher do |input, **_options|
69
- !input.get_elements("//#{type}").empty?
70
- end
71
- .caller do |input, **_options|
72
- input
73
- .get_elements("//#{type}")
74
- .first
75
- .map { |element| [element['name'], element['emoji']] }
76
- .to_h
77
- end
78
- .build
79
- end
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
80
73
  end
81
74
 
75
+ AnimalsXMLScraper = build_xml_scraper(:animals)
76
+ FruitsXMLScraper = build_xml_scraper(:fruits)
77
+
82
78
  tree = CallableTree::Node::Root.new.seekable.append(
83
- JSONParser.build.new.seekable.append(
84
- JSONScraper.build(:animals).new,
85
- JSONScraper.build(:fruits).new
79
+ JSONParser.new.seekable.append(
80
+ AnimalsJSONScraper.new,
81
+ FruitsJSONScraper.new
86
82
  ),
87
- XMLParser.build.new.seekable.append(
88
- XMLScraper.build(:animals).new,
89
- XMLScraper.build(:fruits).new
83
+ XMLParser.new.seekable.append(
84
+ AnimalsXMLScraper.new,
85
+ FruitsXMLScraper.new
90
86
  )
91
87
  )
92
88
 
@@ -0,0 +1,126 @@
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
+ .hookable
24
+ .build
25
+
26
+ XMLParser =
27
+ CallableTree::Node::Internal::Builder
28
+ .new
29
+ .matcher do |input, **_options|
30
+ File.extname(input) == '.xml'
31
+ end
32
+ .caller do |input, **options, &block|
33
+ File.open(input) do |file|
34
+ # The following block call is equivalent to calling `super` in the class style.
35
+ block.call(REXML::Document.new(file), **options)
36
+ end
37
+ end
38
+ .terminator do
39
+ true
40
+ end
41
+ .hookable
42
+ .build
43
+
44
+ def build_json_scraper(type)
45
+ CallableTree::Node::External::Builder
46
+ .new
47
+ .matcher do |input, **_options|
48
+ !!input[type.to_s]
49
+ end
50
+ .caller do |input, **_options|
51
+ input[type.to_s]
52
+ .map { |element| [element['name'], element['emoji']] }
53
+ .to_h
54
+ end
55
+ .hookable
56
+ .build
57
+ end
58
+
59
+ AnimalsJSONScraper = build_json_scraper(:animals)
60
+ FruitsJSONScraper = build_json_scraper(:fruits)
61
+
62
+ def build_xml_scraper(type)
63
+ CallableTree::Node::External::Builder
64
+ .new
65
+ .matcher do |input, **_options|
66
+ !input.get_elements("//#{type}").empty?
67
+ end
68
+ .caller do |input, **_options|
69
+ input
70
+ .get_elements("//#{type}")
71
+ .first
72
+ .map { |element| [element['name'], element['emoji']] }
73
+ .to_h
74
+ end
75
+ .hookable
76
+ .build
77
+ end
78
+
79
+ AnimalsXMLScraper = build_xml_scraper(:animals)
80
+ FruitsXMLScraper = build_xml_scraper(:fruits)
81
+
82
+ loggable = proc do |node|
83
+ indent_size = 2
84
+ blank = ' '
85
+ list_style = '*'
86
+
87
+ node.after_matcher! do |matched, _node_:, **|
88
+ prefix = list_style.rjust(_node_.depth * indent_size - indent_size + list_style.length, blank)
89
+ puts "#{prefix} #{_node_.identity}: [matched: #{matched}]"
90
+ matched
91
+ end
92
+
93
+ if node.is_a?(CallableTree::Node::External)
94
+ input_label = 'Input :'
95
+ output_label = 'Output:'
96
+
97
+ node
98
+ .before_caller! do |input, *, _node_:, **|
99
+ input_prefix = input_label.rjust(_node_.depth * indent_size + input_label.length, blank)
100
+ puts "#{input_prefix} #{input}"
101
+ input
102
+ end
103
+ .after_caller! do |output, _node_:, **|
104
+ output_prefix = output_label.rjust(_node_.depth * indent_size + output_label.length, blank)
105
+ puts "#{output_prefix} #{output}"
106
+ output
107
+ end
108
+ end
109
+ end
110
+
111
+ tree = CallableTree::Node::Root.new.seekable.append(
112
+ JSONParser.new.tap(&loggable).seekable.append(
113
+ AnimalsJSONScraper.new.tap(&loggable).verbosify,
114
+ FruitsJSONScraper.new.tap(&loggable).verbosify
115
+ ),
116
+ XMLParser.new.tap(&loggable).seekable.append(
117
+ AnimalsXMLScraper.new.tap(&loggable).verbosify,
118
+ FruitsXMLScraper.new.tap(&loggable).verbosify
119
+ )
120
+ )
121
+
122
+ Dir.glob("#{__dir__}/../docs/*") do |file|
123
+ options = { foo: :bar }
124
+ pp tree.call(file, **options)
125
+ puts '---'
126
+ end
@@ -5,14 +5,14 @@ require 'callable_tree'
5
5
  module Node
6
6
  class HooksSample
7
7
  include CallableTree::Node::Internal
8
- prepend CallableTree::Node::Hooks::Call
8
+ prepend CallableTree::Node::Hooks::Caller
9
9
  end
10
10
  end
11
11
 
12
12
  Node::HooksSample
13
13
  .new
14
- .before_call do |input, **_options|
15
- puts "before_call input: #{input}"
14
+ .before_caller do |input, **_options|
15
+ puts "before_caller input: #{input}"
16
16
  input + 1
17
17
  end
18
18
  .append(
@@ -22,14 +22,14 @@ Node::HooksSample
22
22
  input * 2
23
23
  end
24
24
  )
25
- .around_call do |input, **_options, &block|
26
- puts "around_call input: #{input}"
25
+ .around_caller do |input, **_options, &block|
26
+ puts "around_caller input: #{input}"
27
27
  output = block.call
28
- puts "around_call output: #{output}"
28
+ puts "around_caller output: #{output}"
29
29
  output * input
30
30
  end
31
- .after_call do |output, **_options|
32
- puts "after_call output: #{output}"
31
+ .after_caller do |output, **_options|
32
+ puts "after_caller output: #{output}"
33
33
  output * 2
34
34
  end
35
35
  .tap do |tree|
@@ -44,7 +44,10 @@ module CallableTree
44
44
  ::Class
45
45
  .new do
46
46
  include node_type
47
- prepend Hooks::Call if hookable
47
+ if hookable
48
+ prepend Hooks::Matcher
49
+ prepend Hooks::Caller
50
+ end
48
51
 
49
52
  if matcher
50
53
  define_method(:match?) do |*inputs, **options|
@@ -15,7 +15,7 @@ module CallableTree
15
15
  private
16
16
 
17
17
  def validate(matcher:, caller:, terminator:)
18
- raise Error 'caller is required' unless caller
18
+ raise Error, 'caller is required' unless caller
19
19
  end
20
20
  end
21
21
  end
@@ -3,7 +3,6 @@
3
3
  module CallableTree
4
4
  module Node
5
5
  module External
6
- # TODO: Add :inputs
7
6
  Output = Struct.new(:value, :options, :routes)
8
7
 
9
8
  module Verbose
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CallableTree
4
+ module Node
5
+ module Hooks
6
+ module Caller
7
+ def self.included(_subclass)
8
+ raise ::CallableTree::Error, "#{self} must be prepended"
9
+ end
10
+
11
+ def before_call(&block)
12
+ clone.before_call!(&block)
13
+ end
14
+
15
+ def before_call!(&block)
16
+ before_caller_callbacks << block
17
+ self
18
+ end
19
+
20
+ def around_call(&block)
21
+ clone.around_call!(&block)
22
+ end
23
+
24
+ def around_call!(&block)
25
+ around_caller_callbacks << block
26
+ self
27
+ end
28
+
29
+ def after_call(&block)
30
+ clone.after_call!(&block)
31
+ end
32
+
33
+ def after_call!(&block)
34
+ after_caller_callbacks << block
35
+ self
36
+ end
37
+
38
+ alias before_caller before_call
39
+ alias before_caller! before_call!
40
+ alias around_caller around_call
41
+ alias around_caller! around_call!
42
+ alias after_caller after_call
43
+ alias after_caller! after_call!
44
+
45
+ def call(*inputs, **options)
46
+ input_head, *input_tail = inputs
47
+
48
+ input_head = before_caller_callbacks.reduce(input_head) do |input_head, callable|
49
+ callable.call(input_head, *input_tail, **options, _node_: self)
50
+ end
51
+
52
+ output =
53
+ if around_caller_callbacks.empty?
54
+ super(input_head, *input_tail, **options)
55
+ else
56
+ around_caller_callbacks_head, *around_caller_callbacks_tail = around_caller_callbacks
57
+ caller = proc { super(input_head, *input_tail, **options) }
58
+
59
+ output =
60
+ around_caller_callbacks_head
61
+ .call(
62
+ input_head,
63
+ *input_tail,
64
+ **options,
65
+ _node_: self
66
+ ) { caller.call }
67
+
68
+ around_caller_callbacks_tail.reduce(output) do |output, callable|
69
+ callable.call(
70
+ input_head,
71
+ *input_tail,
72
+ **options,
73
+ _node_: self
74
+ ) { output }
75
+ end
76
+ end
77
+
78
+ after_caller_callbacks.reduce(output) do |output, callable|
79
+ callable.call(output, **options, _node_: self)
80
+ end
81
+ end
82
+
83
+ def before_caller_callbacks
84
+ @before_caller_callbacks ||= []
85
+ end
86
+
87
+ def around_caller_callbacks
88
+ @around_caller_callbacks ||= []
89
+ end
90
+
91
+ def after_caller_callbacks
92
+ @after_caller_callbacks ||= []
93
+ end
94
+
95
+ private
96
+
97
+ attr_writer :before_caller_callbacks, :around_caller_callbacks, :after_caller_callbacks
98
+
99
+ def initialize_copy(_node)
100
+ super
101
+ self.before_caller_callbacks = before_caller_callbacks.map(&:itself)
102
+ self.around_caller_callbacks = around_caller_callbacks.map(&:itself)
103
+ self.after_caller_callbacks = after_caller_callbacks.map(&:itself)
104
+ end
105
+ end
106
+
107
+ Call = Caller # backward compatibility
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CallableTree
4
+ module Node
5
+ module Hooks
6
+ module Matcher
7
+ def self.included(_subclass)
8
+ raise ::CallableTree::Error, "#{self} must be prepended"
9
+ end
10
+
11
+ def before_matcher(&block)
12
+ clone.before_matcher!(&block)
13
+ end
14
+
15
+ def before_matcher!(&block)
16
+ before_matcher_callbacks << block
17
+ self
18
+ end
19
+
20
+ def around_matcher(&block)
21
+ clone.around_matcher!(&block)
22
+ end
23
+
24
+ def around_matcher!(&block)
25
+ around_matcher_callbacks << block
26
+ self
27
+ end
28
+
29
+ def after_matcher(&block)
30
+ clone.after_matcher!(&block)
31
+ end
32
+
33
+ def after_matcher!(&block)
34
+ after_matcher_callbacks << block
35
+ self
36
+ end
37
+
38
+ def match?(*inputs, **options)
39
+ input_head, *input_tail = inputs
40
+
41
+ input_head = before_matcher_callbacks.reduce(input_head) do |input_head, callable|
42
+ callable.call(input_head, *input_tail, **options, _node_: self)
43
+ end
44
+
45
+ matched =
46
+ if around_matcher_callbacks.empty?
47
+ super(input_head, *input_tail, **options)
48
+ else
49
+ around_matcher_callbacks_head, *around_matcher_callbacks_tail = around_matcher_callbacks
50
+ matcher = proc { super(input_head, *input_tail, **options) }
51
+
52
+ matched =
53
+ around_matcher_callbacks_head
54
+ .call(
55
+ input_head,
56
+ *input_tail,
57
+ **options,
58
+ _node_: self
59
+ ) { matcher.call }
60
+
61
+ around_matcher_callbacks_tail.reduce(matched) do |matched, callable|
62
+ callable.call(
63
+ input_head,
64
+ *input_tail,
65
+ **options,
66
+ _node_: self
67
+ ) { matched }
68
+ end
69
+ end
70
+
71
+ after_matcher_callbacks.reduce(matched) do |matched, callable|
72
+ callable.call(matched, **options, _node_: self)
73
+ end
74
+ end
75
+
76
+ def before_matcher_callbacks
77
+ @before_matcher_callbacks ||= []
78
+ end
79
+
80
+ def around_matcher_callbacks
81
+ @around_matcher_callbacks ||= []
82
+ end
83
+
84
+ def after_matcher_callbacks
85
+ @after_matcher_callbacks ||= []
86
+ end
87
+
88
+ private
89
+
90
+ attr_writer :before_matcher_callbacks, :around_matcher_callbacks, :after_matcher_callbacks
91
+
92
+ def initialize_copy(_node)
93
+ super
94
+ self.before_matcher_callbacks = before_matcher_callbacks.map(&:itself)
95
+ self.around_matcher_callbacks = around_matcher_callbacks.map(&:itself)
96
+ self.after_matcher_callbacks = after_matcher_callbacks.map(&:itself)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -98,9 +98,9 @@ module CallableTree
98
98
  end
99
99
  end
100
100
 
101
- alias_method :seekable?, :seek?
102
- alias_method :seekable, :seek
103
- alias_method :seekable!, :seek!
101
+ alias seekable? seek?
102
+ alias seekable seek
103
+ alias seekable! seek!
104
104
 
105
105
  def broadcast?
106
106
  strategy.is_a?(Strategy::Broadcast)
@@ -122,9 +122,9 @@ module CallableTree
122
122
  end
123
123
  end
124
124
 
125
- alias_method :broadcastable?, :broadcast?
126
- alias_method :broadcastable, :broadcast
127
- alias_method :broadcastable!, :broadcast!
125
+ alias broadcastable? broadcast?
126
+ alias broadcastable broadcast
127
+ alias broadcastable! broadcast!
128
128
 
129
129
  def compose?
130
130
  strategy.is_a?(Strategy::Compose)
@@ -146,9 +146,9 @@ module CallableTree
146
146
  end
147
147
  end
148
148
 
149
- alias_method :composable?, :compose?
150
- alias_method :composable, :compose
151
- alias_method :composable!, :compose!
149
+ alias composable? compose?
150
+ alias composable compose
151
+ alias composable! compose!
152
152
 
153
153
  def outline(&block)
154
154
  key = block ? block.call(self) : identity
@@ -4,7 +4,8 @@ module CallableTree
4
4
  module Node
5
5
  class Root
6
6
  include Internal
7
- prepend Hooks::Call
7
+ prepend Hooks::Matcher
8
+ prepend Hooks::Caller
8
9
 
9
10
  def self.inherited(subclass)
10
11
  raise ::CallableTree::Error, "#{subclass} cannot inherit #{self}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CallableTree
4
- VERSION = '0.3.5'
4
+ VERSION = '0.3.6'
5
5
  end
data/lib/callable_tree.rb CHANGED
@@ -7,7 +7,8 @@ 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'
10
+ require_relative 'callable_tree/node/hooks/matcher'
11
+ require_relative 'callable_tree/node/hooks/caller'
11
12
  require_relative 'callable_tree/node/internal/strategy'
12
13
  require_relative 'callable_tree/node/internal/strategy/broadcast'
13
14
  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.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - jsmmr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-20 00:00:00.000000000 Z
11
+ date: 2022-03-29 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
@@ -33,16 +33,17 @@ files:
33
33
  - bin/console
34
34
  - bin/setup
35
35
  - callable_tree.gemspec
36
- - examples/builder/hooks-call.rb
36
+ - examples/builder/hooks-caller.rb
37
37
  - examples/builder/internal-broadcastable.rb
38
38
  - examples/builder/internal-composable.rb
39
39
  - examples/builder/internal-seekable.rb
40
+ - examples/builder/logging.rb
40
41
  - examples/docs/animals.json
41
42
  - examples/docs/animals.xml
42
43
  - examples/docs/fruits.json
43
44
  - examples/docs/fruits.xml
44
45
  - examples/external-verbosify.rb
45
- - examples/hooks-call.rb
46
+ - examples/hooks-caller.rb
46
47
  - examples/identity.rb
47
48
  - examples/internal-broadcastable.rb
48
49
  - examples/internal-composable.rb
@@ -54,7 +55,8 @@ files:
54
55
  - lib/callable_tree/node/external.rb
55
56
  - lib/callable_tree/node/external/builder.rb
56
57
  - lib/callable_tree/node/external/verbose.rb
57
- - lib/callable_tree/node/hooks/call.rb
58
+ - lib/callable_tree/node/hooks/caller.rb
59
+ - lib/callable_tree/node/hooks/matcher.rb
58
60
  - lib/callable_tree/node/internal.rb
59
61
  - lib/callable_tree/node/internal/builder.rb
60
62
  - lib/callable_tree/node/internal/strategy.rb
@@ -69,7 +71,7 @@ licenses:
69
71
  metadata:
70
72
  homepage_uri: https://github.com/jsmmr/ruby_callable_tree
71
73
  source_code_uri: https://github.com/jsmmr/ruby_callable_tree
72
- changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.5/CHANGELOG.md
74
+ changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.6/CHANGELOG.md
73
75
  post_install_message:
74
76
  rdoc_options: []
75
77
  require_paths:
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CallableTree
4
- module Node
5
- module Hooks
6
- module Call
7
- def self.included(_subclass)
8
- raise ::CallableTree::Error, "#{self} must be prepended"
9
- end
10
-
11
- def before_call(&block)
12
- clone.before_call!(&block)
13
- end
14
-
15
- def before_call!(&block)
16
- before_callbacks << block
17
- self
18
- end
19
-
20
- def around_call(&block)
21
- clone.around_call!(&block)
22
- end
23
-
24
- def around_call!(&block)
25
- around_callbacks << block
26
- self
27
- end
28
-
29
- def after_call(&block)
30
- clone.after_call!(&block)
31
- end
32
-
33
- def after_call!(&block)
34
- after_callbacks << block
35
- self
36
- end
37
-
38
- def call(*inputs, **options)
39
- input_head, *input_tail = inputs
40
-
41
- input_head = before_callbacks.reduce(input_head) do |input_head, callable|
42
- callable.call(input_head, *input_tail, self, **options)
43
- end
44
-
45
- output = super(input_head, *input_tail, **options)
46
-
47
- output = around_callbacks.reduce(output) do |output, callable|
48
- callable.call(input_head, *input_tail, self, **options) { output }
49
- end
50
-
51
- after_callbacks.reduce(output) do |output, callable|
52
- callable.call(output, self, **options)
53
- end
54
- end
55
-
56
- def before_callbacks
57
- @before_callbacks ||= []
58
- end
59
-
60
- def around_callbacks
61
- @around_callbacks ||= []
62
- end
63
-
64
- def after_callbacks
65
- @after_callbacks ||= []
66
- end
67
-
68
- private
69
-
70
- attr_writer :before_callbacks, :around_callbacks, :after_callbacks
71
-
72
- def initialize_copy(_node)
73
- super
74
- self.before_callbacks = before_callbacks.map(&:itself)
75
- self.around_callbacks = around_callbacks.map(&:itself)
76
- self.after_callbacks = after_callbacks.map(&:itself)
77
- end
78
- end
79
- end
80
- end
81
- end