grumlin 0.22.4 → 1.0.0.rc1

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +9 -9
  4. data/Gemfile.lock +10 -8
  5. data/README.md +102 -141
  6. data/Rakefile +1 -1
  7. data/bin/console +18 -3
  8. data/doc/middlewares.md +97 -0
  9. data/grumlin.gemspec +1 -0
  10. data/lib/async/channel.rb +54 -56
  11. data/lib/grumlin/benchmark/repository.rb +10 -14
  12. data/lib/grumlin/client.rb +92 -112
  13. data/lib/grumlin/config.rb +30 -15
  14. data/lib/grumlin/dummy_transaction.rb +13 -15
  15. data/lib/grumlin/edge.rb +18 -20
  16. data/lib/grumlin/expressions/cardinality.rb +5 -9
  17. data/lib/grumlin/expressions/column.rb +5 -9
  18. data/lib/grumlin/expressions/expression.rb +7 -11
  19. data/lib/grumlin/expressions/operator.rb +5 -9
  20. data/lib/grumlin/expressions/order.rb +5 -9
  21. data/lib/grumlin/expressions/p.rb +27 -31
  22. data/lib/grumlin/expressions/pop.rb +5 -9
  23. data/lib/grumlin/expressions/scope.rb +5 -9
  24. data/lib/grumlin/expressions/t.rb +5 -9
  25. data/lib/grumlin/expressions/text_p.rb +5 -9
  26. data/lib/grumlin/expressions/with_options.rb +17 -21
  27. data/lib/grumlin/features/feature_list.rb +8 -12
  28. data/lib/grumlin/features/neptune_features.rb +5 -9
  29. data/lib/grumlin/features/tinkergraph_features.rb +5 -9
  30. data/lib/grumlin/features.rb +8 -10
  31. data/lib/grumlin/middlewares/apply_shortcuts.rb +8 -0
  32. data/lib/grumlin/middlewares/build_query.rb +20 -0
  33. data/lib/grumlin/middlewares/builder.rb +15 -0
  34. data/lib/grumlin/middlewares/cast_results.rb +7 -0
  35. data/lib/grumlin/middlewares/find_blocklisted_steps.rb +14 -0
  36. data/lib/grumlin/middlewares/find_mutating_steps.rb +9 -0
  37. data/lib/grumlin/middlewares/middleware.rb +11 -0
  38. data/lib/grumlin/middlewares/run_query.rb +7 -0
  39. data/lib/grumlin/middlewares/serialize_to_bytecode.rb +9 -0
  40. data/lib/grumlin/middlewares/serialize_to_steps.rb +8 -0
  41. data/lib/grumlin/path.rb +11 -13
  42. data/lib/grumlin/property.rb +14 -16
  43. data/lib/grumlin/query_validators/blocklisted_steps_validator.rb +22 -0
  44. data/lib/grumlin/query_validators/validator.rb +36 -0
  45. data/lib/grumlin/repository/error_handling_strategy.rb +36 -40
  46. data/lib/grumlin/repository/instance_methods.rb +115 -118
  47. data/lib/grumlin/repository.rb +82 -58
  48. data/lib/grumlin/request_dispatcher.rb +55 -57
  49. data/lib/grumlin/request_error_factory.rb +53 -55
  50. data/lib/grumlin/shortcut.rb +19 -21
  51. data/lib/grumlin/shortcuts/properties.rb +12 -16
  52. data/lib/grumlin/shortcuts/storage.rb +67 -74
  53. data/lib/grumlin/shortcuts/upserts.rb +18 -22
  54. data/lib/grumlin/shortcuts.rb +23 -25
  55. data/lib/grumlin/shortcuts_applyer.rb +27 -29
  56. data/lib/grumlin/step.rb +92 -0
  57. data/lib/grumlin/step_data.rb +12 -14
  58. data/lib/grumlin/steppable.rb +24 -22
  59. data/lib/grumlin/steps.rb +51 -54
  60. data/lib/grumlin/steps_serializers/bytecode.rb +53 -56
  61. data/lib/grumlin/steps_serializers/human_readable_bytecode.rb +17 -21
  62. data/lib/grumlin/steps_serializers/serializer.rb +7 -11
  63. data/lib/grumlin/steps_serializers/string.rb +26 -30
  64. data/lib/grumlin/test/rspec/db_cleaner_context.rb +8 -12
  65. data/lib/grumlin/test/rspec/gremlin_context.rb +18 -16
  66. data/lib/grumlin/test/rspec.rb +1 -5
  67. data/lib/grumlin/transaction.rb +26 -27
  68. data/lib/grumlin/transport.rb +71 -73
  69. data/lib/grumlin/traversal_start.rb +31 -33
  70. data/lib/grumlin/traversal_strategies/options_strategy.rb +3 -7
  71. data/lib/grumlin/traverser.rb +5 -7
  72. data/lib/grumlin/typed_value.rb +11 -13
  73. data/lib/grumlin/typing.rb +70 -72
  74. data/lib/grumlin/version.rb +1 -1
  75. data/lib/grumlin/vertex.rb +14 -16
  76. data/lib/grumlin/vertex_property.rb +14 -16
  77. data/lib/grumlin/with_extension.rb +17 -19
  78. data/lib/grumlin.rb +23 -19
  79. metadata +32 -6
  80. data/lib/grumlin/action.rb +0 -92
  81. data/lib/grumlin/sugar.rb +0 -15
data/lib/async/channel.rb CHANGED
@@ -1,74 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Async
4
- # Channel is a wrapper around Async::Queue that provides
5
- # a protocol and handy tools for passing data, exceptions and closing.
6
- # It is designed to be used only with one publisher and one subscriber
7
- class Channel
8
- class ChannelError < StandardError; end
9
-
10
- class ChannelClosedError < ChannelError; end
11
-
12
- def initialize
13
- @queue = Async::Queue.new
14
- @closed = false
15
- end
3
+ # Channel is a wrapper around Async::Queue that provides
4
+ # a protocol and handy tools for passing data, exceptions and closing.
5
+ # It is designed to be used only with one publisher and one subscriber
6
+ class Async::Channel
7
+ class ChannelError < StandardError; end
16
8
 
17
- def closed?
18
- @closed
19
- end
9
+ class ChannelClosedError < ChannelError; end
20
10
 
21
- def open?
22
- !@closed
23
- end
11
+ def initialize
12
+ @queue = Async::Queue.new
13
+ @closed = false
14
+ end
24
15
 
25
- # Methods for a publisher
26
- def <<(payload)
27
- raise(ChannelClosedError, "Cannot send to a closed channel") if @closed
16
+ def closed?
17
+ @closed
18
+ end
28
19
 
29
- @queue << [:payload, payload]
30
- end
20
+ def open?
21
+ !@closed
22
+ end
31
23
 
32
- def exception(exception)
33
- raise(ChannelClosedError, "Cannot send to a closed channel") if closed?
24
+ # Methods for a publisher
25
+ def <<(payload)
26
+ raise(ChannelClosedError, "Cannot send to a closed channel") if @closed
34
27
 
35
- @queue << [:exception, exception]
36
- end
28
+ @queue << [:payload, payload]
29
+ end
37
30
 
38
- def close
39
- return if closed?
31
+ def exception(exception)
32
+ raise(ChannelClosedError, "Cannot send to a closed channel") if closed?
40
33
 
41
- @queue << [:close]
42
- @closed = true
43
- end
34
+ @queue << [:exception, exception]
35
+ end
44
36
 
45
- def close!
46
- return if closed?
37
+ def close
38
+ return if closed?
47
39
 
48
- exception(ChannelClosedError.new("Channel was forcefully closed"))
49
- close
50
- end
40
+ @queue << [:close]
41
+ @closed = true
42
+ end
51
43
 
52
- # Methods for a subscriber
53
- def dequeue
54
- each do |payload| # rubocop:disable Lint/UnreachableLoop this is intended
55
- return payload
56
- end
44
+ def close!
45
+ return if closed?
46
+
47
+ exception(ChannelClosedError.new("Channel was forcefully closed"))
48
+ close
49
+ end
50
+
51
+ # Methods for a subscriber
52
+ def dequeue
53
+ each do |payload| # rubocop:disable Lint/UnreachableLoop this is intended
54
+ return payload
57
55
  end
56
+ end
58
57
 
59
- def each
60
- raise(ChannelClosedError, "Cannot receive from a closed channel") if closed?
61
-
62
- @queue.each do |type, payload|
63
- case type
64
- when :exception
65
- payload.set_backtrace(caller + (payload.backtrace || [])) # A hack to preserve full backtrace
66
- raise payload
67
- when :payload
68
- yield payload
69
- when :close
70
- break
71
- end
58
+ def each
59
+ raise(ChannelClosedError, "Cannot receive from a closed channel") if closed?
60
+
61
+ @queue.each do |type, payload|
62
+ case type
63
+ when :exception
64
+ payload.set_backtrace(caller + (payload.backtrace || [])) # A hack to preserve full backtrace
65
+ raise payload
66
+ when :payload
67
+ yield payload
68
+ when :close
69
+ break
72
70
  end
73
71
  end
74
72
  end
@@ -1,21 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Benchmark
5
- class Repository
6
- extend Grumlin::Repository
3
+ class Grumlin::Benchmark::Repository
4
+ extend Grumlin::Repository
7
5
 
8
- shortcut :simple_test do
9
- self.V
10
- end
6
+ shortcut :simple_test do
7
+ self.V
8
+ end
11
9
 
12
- def simple_test
13
- g.V.bytecode.serialize
14
- end
10
+ def simple_test
11
+ g.V.bytecode.serialize
12
+ end
15
13
 
16
- def simple_test_with_shortcut
17
- g.simple_test.bytecode.serialize
18
- end
19
- end
14
+ def simple_test_with_shortcut
15
+ g.simple_test.bytecode.serialize
20
16
  end
21
17
  end
@@ -1,143 +1,123 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Client
5
- class PoolResource < Async::Pool::Resource
6
- attr_reader :client
7
-
8
- def self.call
9
- config = Grumlin.config
10
- new(config.url, client_factory: config.client_factory, concurrency: config.client_concurrency)
11
- end
12
-
13
- def initialize(url, client_factory:, concurrency: 1, parent: Async::Task.current)
14
- super(concurrency)
15
- @client = client_factory.call(url, parent).tap(&:connect)
16
- @parent = parent
17
- end
18
-
19
- def closed?
20
- !@client.connected?
21
- end
3
+ class Grumlin::Client
4
+ class PoolResource < Async::Pool::Resource
5
+ attr_reader :client
22
6
 
23
- def close
24
- @client.close
25
- end
7
+ def self.call
8
+ config = Grumlin.config
9
+ new(config.url, client_factory: config.client_factory, concurrency: config.client_concurrency)
10
+ end
26
11
 
27
- def write(bytecode, session_id: nil)
28
- @client.write(bytecode, session_id: session_id)
29
- ensure
30
- @count += 1
31
- end
12
+ def initialize(url, client_factory:, concurrency: 1, parent: Async::Task.current)
13
+ super(concurrency)
14
+ @client = client_factory.call(url, parent).tap(&:connect)
15
+ @parent = parent
16
+ end
32
17
 
33
- def viable?
34
- !closed?
35
- end
18
+ def closed?
19
+ !@client.connected?
20
+ end
36
21
 
37
- def reusable?
38
- !closed?
39
- end
22
+ def close
23
+ @client.close
40
24
  end
41
25
 
42
- include Console
26
+ def write(query)
27
+ @client.write(query)
28
+ ensure
29
+ @count += 1
30
+ end
43
31
 
44
- # Client is not reusable. Once closed should be recreated.
45
- def initialize(url, parent: Async::Task.current, **client_options)
46
- @url = url
47
- @client_options = client_options
48
- @parent = parent
49
- @request_dispatcher = nil
50
- @transport = nil
32
+ def viable?
33
+ !closed?
51
34
  end
52
35
 
53
- def connect
54
- raise ClientClosedError if @closed
55
-
56
- @transport = build_transport
57
- response_channel = @transport.connect
58
- @request_dispatcher = RequestDispatcher.new
59
- @response_task = @parent.async do
60
- response_channel.each do |response|
61
- @request_dispatcher.add_response(response)
62
- end
63
- rescue Async::Stop, Async::TimeoutError, StandardError
64
- close(check_requests: false)
65
- end
66
- logger.debug(self, "Connected")
36
+ def reusable?
37
+ !closed?
67
38
  end
39
+ end
68
40
 
69
- # Before calling close the user must ensure that:
70
- # 1) There are no ongoing requests
71
- # 2) There will be no new writes after
72
- def close(check_requests: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
73
- return if @closed
41
+ include Console
74
42
 
75
- @closed = true
43
+ # Client is not reusable. Once closed should be recreated.
44
+ def initialize(url, parent: Async::Task.current, **client_options)
45
+ @url = url
46
+ @client_options = client_options
47
+ @parent = parent
48
+ @request_dispatcher = nil
49
+ @transport = nil
50
+ end
76
51
 
77
- @transport&.close
78
- @transport&.wait
52
+ def connect
53
+ raise ClientClosedError if @closed
79
54
 
80
- @response_task&.stop
81
- @response_task&.wait
55
+ @transport = build_transport
56
+ response_channel = @transport.connect
57
+ @request_dispatcher = Grumlin::RequestDispatcher.new
58
+ @response_task = @parent.async do
59
+ response_channel.each do |response|
60
+ @request_dispatcher.add_response(response)
61
+ end
62
+ rescue Async::Stop, Async::TimeoutError, StandardError
63
+ close(check_requests: false)
64
+ end
65
+ logger.debug(self, "Connected")
66
+ end
82
67
 
83
- return if @request_dispatcher&.requests&.empty?
68
+ # Before calling close the user must ensure that:
69
+ # 1) There are no ongoing requests
70
+ # 2) There will be no new writes after
71
+ def close(check_requests: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
72
+ return if @closed
84
73
 
85
- @request_dispatcher.clear unless check_requests
74
+ @closed = true
86
75
 
87
- raise ResourceLeakError, "Request list is not empty: #{@request_dispatcher.requests}" if check_requests
88
- ensure
89
- logger.debug(self, "Closed")
90
- end
76
+ @transport&.close
77
+ @transport&.wait
91
78
 
92
- def connected?
93
- @transport&.connected? || false
94
- end
79
+ @response_task&.stop
80
+ @response_task&.wait
95
81
 
96
- # TODO: support yielding
97
- def write(bytecode, session_id: nil)
98
- raise NotConnectedError unless connected?
82
+ return if @request_dispatcher&.requests&.empty?
99
83
 
100
- request = to_query(bytecode, session_id: session_id)
84
+ @request_dispatcher.clear unless check_requests
101
85
 
102
- channel = @request_dispatcher.add_request(request)
103
- begin
104
- @transport.write(request)
105
- channel.dequeue.flat_map { |item| Typing.cast(item) }
106
- rescue Async::Stop, Async::TimeoutError
107
- close(check_requests: false)
108
- raise
109
- end
110
- end
86
+ raise ResourceLeakError, "Request list is not empty: #{@request_dispatcher.requests}" if check_requests
87
+ ensure
88
+ logger.debug(self, "Closed")
89
+ end
111
90
 
112
- def inspect
113
- "<#{self.class} url=#{@url} connected=#{connected?}>"
114
- end
91
+ def connected?
92
+ @transport&.connected? || false
93
+ end
115
94
 
116
- def to_s
117
- inspect
95
+ # TODO: support yielding
96
+ def write(query)
97
+ raise NotConnectedError unless connected?
98
+
99
+ channel = @request_dispatcher.add_request(query)
100
+ begin
101
+ @transport.write(query)
102
+ channel.dequeue
103
+ rescue Async::Stop, Async::TimeoutError
104
+ close(check_requests: false)
105
+ raise
118
106
  end
107
+ end
119
108
 
120
- private
109
+ def inspect
110
+ "<#{self.class} url=#{@url} connected=#{connected?}>"
111
+ end
121
112
 
122
- # This might be overridden in successors
123
- def build_transport
124
- Transport.new(@url, parent: @parent, **@client_options)
125
- end
113
+ def to_s
114
+ inspect
115
+ end
126
116
 
127
- def to_query(bytecode, session_id:)
128
- {
129
- requestId: SecureRandom.uuid,
130
- op: :bytecode,
131
- processor: session_id ? :session : :traversal,
132
- args: {
133
- gremlin: {
134
- :@type => "g:Bytecode",
135
- :@value => bytecode.serialize
136
- },
137
- aliases: { g: :g },
138
- session: session_id
139
- }.compact
140
- }
141
- end
117
+ private
118
+
119
+ # This might be overridden in successors
120
+ def build_transport
121
+ Grumlin::Transport.new(@url, parent: @parent, **@client_options)
142
122
  end
143
123
  end
@@ -1,26 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Config
5
- attr_accessor :url, :pool_size, :client_concurrency, :client_factory, :provider
3
+ class Grumlin::Config
4
+ attr_accessor :url, :pool_size, :client_concurrency, :client_factory, :provider
6
5
 
7
- SUPPORTED_PROVIDERS = %i[neptune tinkergraph].freeze
6
+ SUPPORTED_PROVIDERS = [:neptune, :tinkergraph].freeze
8
7
 
9
- class ConfigurationError < Grumlin::Error; end
8
+ DEFAULT_MIDDLEWARES = Grumlin::Middlewares::Builder.new do |b|
9
+ b.use Grumlin::Middlewares::SerializeToSteps
10
+ b.use Grumlin::Middlewares::ApplyShortcuts
11
+ b.use Grumlin::Middlewares::SerializeToBytecode
12
+ b.use Grumlin::Middlewares::BuildQuery
13
+ b.use Grumlin::Middlewares::CastResults
14
+ b.use Grumlin::Middlewares::RunQuery
15
+ end
10
16
 
11
- class UnknownProviderError < ConfigurationError; end
17
+ class ConfigurationError < Grumlin::Error; end
12
18
 
13
- def initialize
14
- @pool_size = 10
15
- @client_concurrency = 5
16
- @provider = :tinkergraph
17
- @client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
18
- end
19
+ class UnknownProviderError < ConfigurationError; end
19
20
 
20
- def validate!
21
- return if SUPPORTED_PROVIDERS.include?(provider.to_sym)
21
+ def initialize
22
+ @pool_size = 10
23
+ @client_concurrency = 5
24
+ @provider = :tinkergraph
25
+ @client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
26
+ end
22
27
 
23
- raise UnknownProviderError, "provider '#{provider}' is unknown. Supported providers: #{SUPPORTED_PROVIDERS}"
28
+ def middlewares
29
+ @middlewares ||= Grumlin::Middlewares::Builder.new do |b|
30
+ b.use DEFAULT_MIDDLEWARES
24
31
  end
32
+ yield(@middlewares) if block_given?
33
+ @middlewares
34
+ end
35
+
36
+ def validate!
37
+ return if SUPPORTED_PROVIDERS.include?(provider.to_sym)
38
+
39
+ raise UnknownProviderError, "provider '#{provider}' is unknown. Supported providers: #{SUPPORTED_PROVIDERS}"
25
40
  end
26
41
  end
@@ -1,25 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class DummyTransaction < Transaction
5
- attr_reader :uuid
3
+ class Grumlin::DummyTransaction < Grumlin::Transaction
4
+ attr_reader :uuid
6
5
 
7
- include Console
6
+ include Console
8
7
 
9
- def initialize(traversal_start_class, pool: Grumlin.default_pool) # rubocop:disable Lint/MissingSuper, Lint/UnusedMethodArgument
10
- @traversal_start_class = traversal_start_class
8
+ def initialize(traversal_start_class, middlewares:, pool: nil) # rubocop:disable Lint/MissingSuper, Lint/UnusedMethodArgument
9
+ @traversal_start_class = traversal_start_class
11
10
 
12
- logger.info(self) do
13
- "#{Grumlin.config.provider} does not support transactions. commit and rollback are ignored, data will be saved"
14
- end
11
+ logger.info(self) do
12
+ "#{Grumlin.config.provider} does not support transactions. commit and rollback are ignored, data will be saved"
15
13
  end
14
+ end
16
15
 
17
- def commit
18
- nil
19
- end
16
+ def commit
17
+ nil
18
+ end
20
19
 
21
- def rollback
22
- nil
23
- end
20
+ def rollback
21
+ nil
24
22
  end
25
23
  end
data/lib/grumlin/edge.rb CHANGED
@@ -1,28 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Edge
5
- attr_reader :label, :id, :inVLabel, :outVLabel, :inV, :outV
3
+ class Grumlin::Edge
4
+ attr_reader :label, :id, :inVLabel, :outVLabel, :inV, :outV
6
5
 
7
- def initialize(label:, id:, inVLabel:, outVLabel:, inV:, outV:)
8
- @label = label
9
- @id = Typing.cast(id)
10
- @inVLabel = inVLabel
11
- @outVLabel = outVLabel
12
- @inV = Typing.cast(inV)
13
- @outV = Typing.cast(outV)
14
- end
6
+ def initialize(label:, id:, inVLabel:, outVLabel:, inV:, outV:)
7
+ @label = label
8
+ @id = Grumlin::Typing.cast(id)
9
+ @inVLabel = inVLabel
10
+ @outVLabel = outVLabel
11
+ @inV = Grumlin::Typing.cast(inV)
12
+ @outV = Grumlin::Typing.cast(outV)
13
+ end
15
14
 
16
- def ==(other)
17
- self.class == other.class && @label == other.label && @id == other.id
18
- end
15
+ def ==(other)
16
+ self.class == other.class && @label == other.label && @id == other.id
17
+ end
19
18
 
20
- def inspect
21
- "e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
22
- end
19
+ def inspect
20
+ "e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
21
+ end
23
22
 
24
- def to_s
25
- inspect
26
- end
23
+ def to_s
24
+ inspect
27
25
  end
28
26
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Cardinality
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :cardinality).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Cardinality
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :cardinality).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Cardinality")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Cardinality")
14
10
  end
15
11
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Column
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :column).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Column
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :column).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Column")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Column")
14
10
  end
15
11
  end
@@ -1,17 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Expression
6
- def define_steps(steps, tool_name)
7
- steps.each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
3
+ module Grumlin::Expressions::Expression
4
+ def define_steps(steps, tool_name)
5
+ steps.each do |step|
6
+ define_method step do
7
+ name = "@#{step}"
8
+ return instance_variable_get(name) if instance_variable_defined?(name)
11
9
 
12
- instance_variable_set(name, TypedValue.new(type: tool_name, value: step))
13
- end
14
- end
10
+ instance_variable_set(name, Grumlin::TypedValue.new(type: tool_name, value: step))
15
11
  end
16
12
  end
17
13
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Operator
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :operator).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Operator
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :operator).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Operator")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Operator")
14
10
  end
15
11
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Order
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :order).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Order
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :order).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Order")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Order")
14
10
  end
15
11
  end