callable_tree 0.3.3 → 0.3.4

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: 8cdb3e4595a6233e401511b3a1cb371cacc3bcf6aa38aa78779928a532124103
4
+ data.tar.gz: abfb837062826d1c3ad644b127eac6b54241106b6feb29f4750add2104676750
5
5
  SHA512:
6
- metadata.gz: 14883eaed6a4655f62908ae53dabadd007e56befb50cb8d5b02790d91441afe3749ecf00019709a5ba39b8bfaafeaa8e475a318e62d1a93f21511ef3611d4238
7
- data.tar.gz: b58152e34c1e7b7c3f9941715d7f512f71d40b1abbacbb7481e965ceb34969117c56b4a9ee218ed62f087dedc7d85ffdde1d9f43ab6beb25aa6da8b89b9dfde1
6
+ metadata.gz: a44400b690e3b04f9f1abef9eacc7ddd648121015c3d0e919cf4a0bfab8f4ffa30ffa55dc71b9eb8a4eb174be64ab83a46f1c71457107169f32271182998fceb
7
+ data.tar.gz: 52ece74206ae1cb94cd53e9920a8cdc29aa00874dee0f4a4c214dcf679d1d0d2374217585828eebf642374ca4676a503e819b4a16fbf5c26fa7004b81da971ff
@@ -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,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.4] - 2022-03-13
4
+
5
+ - Add `CallableTree::Node::Internal::Builder`. (experimental)
6
+ See `examples/builder/*.rb` for details.
7
+ - Add `CallableTree::Node::External::Builder`. (experimental)
8
+ See `examples/builder/*.rb` for details.
9
+
3
10
  ## [0.3.3] - 2022-02-19
4
11
 
5
12
  - 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.4)
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
@@ -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_call do |input, **_options|
14
+ puts "before_call 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_call do |input, **_options, &block|
25
+ puts "around_call input: #{input}"
26
+ output = block.call
27
+ puts "around_call output: #{output}"
28
+ output * input
29
+ end
30
+ .after_call do |output, **_options|
31
+ puts "after_call 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.broadcast.append(
59
+ LessThan5.new.broadcast.append(
60
+ Multiply2.new,
61
+ Add1.new
62
+ ),
63
+ LessThan10.new.broadcast.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.compose.append(
59
+ LessThan5.new.compose.append(
60
+ Multiply2.new,
61
+ Add1.new
62
+ ),
63
+ LessThan10.new.compose.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,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'callable_tree'
4
+ require 'json'
5
+ require 'rexml/document'
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
+ .terminater do
22
+ true
23
+ end
24
+ .build
25
+ 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
+ .terminater do
42
+ true
43
+ end
44
+ .build
45
+ end
46
+ end
47
+
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
61
+ end
62
+ end
63
+
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
80
+ end
81
+
82
+ tree = CallableTree::Node::Root.new.append(
83
+ JSONParser.build.new.append(
84
+ JSONScraper.build(:animals).new,
85
+ JSONScraper.build(:fruits).new
86
+ ),
87
+ XMLParser.build.new.append(
88
+ XMLScraper.build(:animals).new,
89
+ XMLScraper.build(:fruits).new
90
+ )
91
+ )
92
+
93
+ Dir.glob("#{__dir__}/../docs/*") do |file|
94
+ options = { foo: :bar }
95
+ pp tree.call(file, **options)
96
+ puts '---'
97
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CallableTree
4
+ module Node
5
+ module Builder
6
+ def matcher(&block)
7
+ @matcher = block
8
+ self
9
+ end
10
+
11
+ def caller(&block)
12
+ @caller = block
13
+ self
14
+ end
15
+
16
+ def terminater(&block)
17
+ @terminater = block
18
+ self
19
+ end
20
+
21
+ def hookable(hookable = true)
22
+ @hookable = hookable
23
+ self
24
+ end
25
+
26
+ def build(node_type:)
27
+ matcher = @matcher
28
+ caller = @caller
29
+ terminater = @terminater
30
+ hookable = @hookable
31
+
32
+ validate(
33
+ matcher: matcher,
34
+ caller: caller,
35
+ terminater: terminater
36
+ )
37
+
38
+ ::Class
39
+ .new do
40
+ include node_type
41
+ prepend Hooks::Call if hookable
42
+
43
+ if matcher
44
+ define_method(:match?) do |*inputs, **options|
45
+ matcher.call(*inputs, **options) do |*inputs, **options|
46
+ super(*inputs, **options)
47
+ end
48
+ end
49
+ end
50
+
51
+ if caller
52
+ define_method(:call) do |*inputs, **options|
53
+ caller.call(*inputs, **options) do |*inputs, **options|
54
+ super(*inputs, **options)
55
+ end
56
+ end
57
+ end
58
+
59
+ if terminater
60
+ define_method(:terminate?) do |output, *inputs, **options|
61
+ terminater.call(output, *inputs, **options) do |output, *inputs, **options|
62
+ super(output, *inputs, **options)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def validate(matcher:, caller:, terminater:)
72
+ raise ::CallableTree::Error, 'Not implemented'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CallableTree
4
+ module Node
5
+ module External
6
+ class Builder
7
+ include Node::Builder
8
+
9
+ class Error < StandardError; end
10
+
11
+ def build
12
+ super(node_type: External)
13
+ end
14
+
15
+ private
16
+
17
+ def validate(matcher:, caller:, terminater:)
18
+ raise Error 'caller is required' unless caller
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CallableTree
4
+ module Node
5
+ module Internal
6
+ class Builder
7
+ include Node::Builder
8
+
9
+ def build
10
+ super(node_type: Internal)
11
+ end
12
+
13
+ private
14
+
15
+ def validate(matcher:, caller:, terminater:)
16
+ # noop
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CallableTree
4
- VERSION = '0.3.3'
4
+ VERSION = '0.3.4'
5
5
  end
data/lib/callable_tree.rb CHANGED
@@ -15,4 +15,7 @@ require_relative 'callable_tree/node/internal/strategy/compose'
15
15
  require_relative 'callable_tree/node/external/verbose'
16
16
  require_relative 'callable_tree/node/external'
17
17
  require_relative 'callable_tree/node/internal'
18
+ require_relative 'callable_tree/node/builder'
19
+ require_relative 'callable_tree/node/internal/builder'
20
+ require_relative 'callable_tree/node/external/builder'
18
21
  require_relative 'callable_tree/node/root'
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.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - jsmmr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-19 00:00:00.000000000 Z
11
+ date: 2022-03-13 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,6 +33,10 @@ files:
33
33
  - bin/console
34
34
  - bin/setup
35
35
  - callable_tree.gemspec
36
+ - examples/builder/hooks-call.rb
37
+ - examples/builder/internal-broadcast.rb
38
+ - examples/builder/internal-compose.rb
39
+ - examples/builder/internal-seek.rb
36
40
  - examples/docs/animals.json
37
41
  - examples/docs/animals.xml
38
42
  - examples/docs/fruits.json
@@ -46,10 +50,13 @@ files:
46
50
  - examples/logging.rb
47
51
  - lib/callable_tree.rb
48
52
  - lib/callable_tree/node.rb
53
+ - lib/callable_tree/node/builder.rb
49
54
  - lib/callable_tree/node/external.rb
55
+ - lib/callable_tree/node/external/builder.rb
50
56
  - lib/callable_tree/node/external/verbose.rb
51
57
  - lib/callable_tree/node/hooks/call.rb
52
58
  - lib/callable_tree/node/internal.rb
59
+ - lib/callable_tree/node/internal/builder.rb
53
60
  - lib/callable_tree/node/internal/strategy.rb
54
61
  - lib/callable_tree/node/internal/strategy/broadcast.rb
55
62
  - lib/callable_tree/node/internal/strategy/compose.rb
@@ -62,7 +69,7 @@ licenses:
62
69
  metadata:
63
70
  homepage_uri: https://github.com/jsmmr/ruby_callable_tree
64
71
  source_code_uri: https://github.com/jsmmr/ruby_callable_tree
65
- changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.3/CHANGELOG.md
72
+ changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.4/CHANGELOG.md
66
73
  post_install_message:
67
74
  rdoc_options: []
68
75
  require_paths:
@@ -78,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
85
  - !ruby/object:Gem::Version
79
86
  version: '0'
80
87
  requirements: []
81
- rubygems_version: 3.3.3
88
+ rubygems_version: 3.3.7
82
89
  signing_key:
83
90
  specification_version: 4
84
91
  summary: Builds a tree by linking callable nodes. The nodes that match the conditions