teckel 0.8.0 → 0.9.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 213ed6f9b3d25db8b7fc284ced55aa1a3a71b4ec54f10fd3ed3bf4e0a315dbd3
4
- data.tar.gz: d013f110763117b066987bfb6c085e8682db372856ea7ab27f4803858be96e3c
3
+ metadata.gz: c8dc1958f2645a6c57178a595b7d4364c9b2613e3c5adc532e0c8fd0cc8c2c22
4
+ data.tar.gz: cc0ef87983b17af9c16df5f4cc77a826a445fb7dc1f38db4de6cef7eef3b27c1
5
5
  SHA512:
6
- metadata.gz: 82db9106f0da688411be738866692455653eb59298afa01ba24500975b0498bf9a164f9f59e2741a4ed9c0c252174bd86fa71dd4204338fe04424d961c21621b
7
- data.tar.gz: 6c693373c212e3b127dde042fdaba1ab7865d813cba17d0624a73a62e62589fc68bfe86ed93b9e7c32295deb6053411e4ea0cf57f0897b6f8e7e339ce60dd7be
6
+ metadata.gz: 9b9e5dde43b07ec1ae8fb6a1964990cdbdac430bd2c3ba4e73fd137fbeac3f1e4a3faf10e05098da00414a8ed17b6b8ce4316593ea1160bf976aeb2bc550ab6d
7
+ data.tar.gz: 5fd5bd9a76fcf3ad4794de79e94eaba128dc6cbcac1a12e92eafa0aef36d5b18496d8d509738706f23fe555e6d482c21e20cd0384c756e4b02952d4ce52bf770
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changes
2
2
 
3
+ ## 0.9.0
4
+
5
+ - Internal housekeeping
6
+ - Add ruby 3.4 and 'head' to CI
7
+ - Ruby < 3 won't run mutation test
8
+ - moved to standard.rb for linting and formatting
9
+ - removed usage of `forwardable` in favor of explicit delegation methods
10
+ - renamed internal `Teckel::Config.for` to `get_or_set`
11
+ - renamed internal `Teckel::Operation::Config.get_set_constructor` to `get_or_set_constructor`
12
+ - fixed specs that test backtrace outputs on ruby 3.4
13
+ - Documentation now uses modern (Ruby 3.4) output syntax. (`{foo: 1}` is now printed as is, instead of `{:foo => 1}`
14
+
3
15
  ## 0.8.0
4
16
 
5
17
  - Add mutation testing (currently about 80% covered)
@@ -7,11 +19,13 @@
7
19
  When using the default result implementation, nothing changes for you.
8
20
  When you manually pass anything else into it, `succesful?` will return this value. The `failure` and `success` methods
9
21
  work on the "Truthy" value of `successful`
22
+
10
23
  ```ruby
11
24
  result = Result.new(some_value, 42)
12
25
  result.successful?
13
26
  # => 42
14
27
  ```
28
+
15
29
  - Change: `freeze`ing an `Operation` or `Chain` will also freeze their internal config (input, output, steps, etc.)
16
30
 
17
31
  Internal:
@@ -25,20 +39,20 @@ Internal:
25
39
  - Breaking: `Teckel::Chain` will not be required by default. require manually if needed `require "teckel/chain"` [GH-24]
26
40
  - Breaking: Internally, `Teckel::Operation::Runner` instead of `:success` and `:failure` now only uses `:halt` as it's throw-catch symbol. [GH-26]
27
41
  - Add: Using the default `Teckel::Operation::Runner`, `input_constructor` and `result_constructor` will be executed
28
- within the context of the operation instance. This allows for `input_constructor` to call `fail!` and `success!`
42
+ within the context of the operation instance. This allows for `input_constructor` to call `fail!` and `success!`
29
43
  without ever `call`ing the operation. [GH-26]
30
44
 
31
-
32
45
  ## 0.6.0
33
46
 
34
47
  - Breaking: Operations return values will be ignored. [GH-21]
35
- * You'll need to use `success!` or `failure!`
36
- * `success!` and `failure!` are now implemented on the `Runner`, which makes it easier to change their behavior (including the one above).
48
+ - You'll need to use `success!` or `failure!`
49
+ - `success!` and `failure!` are now implemented on the `Runner`, which makes it easier to change their behavior (including the one above).
37
50
 
38
51
  ## 0.5.0
39
52
 
40
53
  - Fix: calling chain with settings and no input [GH-14]
41
54
  - Add: Default settings for Operation and Chains [GH-17], [GH-18]
55
+
42
56
  ```ruby
43
57
  class MyOperation
44
58
  include Teckel::Operation
@@ -68,6 +82,7 @@ Internal:
68
82
  ```
69
83
 
70
84
  Internal:
85
+
71
86
  - Move operation and chain config dsl methods into own module [GH-15]
72
87
  - Code simplifications [GH-16]
73
88
 
@@ -77,6 +92,7 @@ Internal:
77
92
  - `#finalize!` no longer freezes the entire Operation or Chain class, only it's settings. [GH-13]
78
93
  - Add simple support for using Base classes. [GH-10]
79
94
  Removes global configuration `Teckel::Config.default_constructor`
95
+
80
96
  ```ruby
81
97
  class ApplicationOperation
82
98
  include Teckel::Operation
@@ -94,17 +110,21 @@ Internal:
94
110
  # you cannot call `finalize!` on partially declared Operations
95
111
  end
96
112
  ```
113
+
97
114
  - Add support for setting your own Result objects. [GH-9]
98
115
  - They should include and implement `Teckel::Result` which is needed by `Chain`.
99
116
  - `Chain::StepFailure` got replaced with `Chain::Result`.
100
117
  - the `Teckel::Operation::Results` module was removed. To let Operation use the default Result object, use the new helper `result!` instead.
101
118
  - Add "settings"/dependency injection to Operation and Chains. [GH-7]
119
+
102
120
  ```ruby
103
121
  MyOperation.with(logger: STDOUT).call(params)
104
122
 
105
123
  MyChain.with(some_step: { logger: STDOUT }).call(params)
106
124
  ```
125
+
107
126
  - [GH-5] Add support for ruby 2.7 pattern matching on Operation and Chain results. Both, array and hash notations are supported:
127
+
108
128
  ```ruby
109
129
  case MyOperation.call(params)
110
130
  in [false, value]
@@ -122,19 +142,20 @@ Internal:
122
142
  # handle success
123
143
  end
124
144
  ```
145
+
125
146
  - Fix setting a config twice to raise an error
126
147
 
127
148
  ## 0.3.0
128
149
 
129
150
  - `finalize!`'ing a Chain will also finalize all it's Operations
130
151
  - Changed attribute naming of `StepFailure`:
131
- + `.operation` will now give the operation class of the step - was `.step` before
132
- + `.step` will now give the name of the step (which Operation failed) - was `.step_name` before
152
+ - `.operation` will now give the operation class of the step - was `.step` before
153
+ - `.step` will now give the name of the step (which Operation failed) - was `.step_name` before
133
154
 
134
155
  ## 0.2.0
135
156
 
136
157
  - Around Hooks for Chains
137
- - `finalize!`
158
+ - `finalize!`
138
159
  - freezing Chains and Operations, to prevent further changes
139
160
  - Operations check their config and raise if any is missing
140
161
 
@@ -17,7 +17,7 @@ module Teckel
17
17
  #
18
18
  # @return [<Step>]
19
19
  def steps
20
- @config.for(:steps) { [] }
20
+ @config.get_or_set(:steps) { [] }
21
21
  end
22
22
 
23
23
  # Set or get the optional around hook.
@@ -26,9 +26,9 @@ module Teckel
26
26
  # chain ({Runner}) and the second argument the +input+ data. The hook also
27
27
  # needs to return the result.
28
28
  #
29
- # @param callable [Proc,{#call}] The hook to pass chain execution control to. (nil)
29
+ # @param callable [Proc,#call] The hook to pass chain execution control to. (nil)
30
30
  #
31
- # @return [Proc,{#call}] The configured hook
31
+ # @return [Proc,#call] The configured hook
32
32
  #
33
33
  # @example Around hook with block
34
34
  # OUTPUTS = []
@@ -62,7 +62,7 @@ module Teckel
62
62
  # OUTPUTS #=> ["before start", "after start"]
63
63
  # result.success #=> { some: "test" }
64
64
  def around(callable = nil, &block)
65
- @config.for(:around, callable || block)
65
+ @config.get_or_set(:around, callable || block)
66
66
  end
67
67
 
68
68
  # @!attribute [r] runner()
@@ -73,7 +73,7 @@ module Teckel
73
73
  # @param klass [Class] A class like the {Runner}
74
74
  # @!visibility protected
75
75
  def runner(klass = nil)
76
- @config.for(:runner, klass) { Runner }
76
+ @config.get_or_set(:runner, klass) { Runner }
77
77
  end
78
78
 
79
79
  # @overload result()
@@ -85,7 +85,7 @@ module Teckel
85
85
  # @param klass [Class] The +result+ class
86
86
  # @return [Class] The +result+ class configured
87
87
  def result(klass = nil)
88
- @config.for(:result, klass) { const_defined?(:Result, false) ? self::Result : Teckel::Chain::Result }
88
+ @config.get_or_set(:result, klass) { const_defined?(:Result, false) ? self::Result : Teckel::Chain::Result }
89
89
  end
90
90
 
91
91
  # @overload result_constructor()
@@ -143,7 +143,7 @@ module Teckel
143
143
  def result_constructor(sym_or_proc = nil)
144
144
  constructor = build_constructor(result, sym_or_proc) unless sym_or_proc.nil?
145
145
 
146
- @config.for(:result_constructor, constructor) {
146
+ @config.get_or_set(:result_constructor, constructor) {
147
147
  build_constructor(result, Teckel::DEFAULT_CONSTRUCTOR)
148
148
  } || raise(MissingConfigError, "Missing result_constructor config for #{self}")
149
149
  end
@@ -153,7 +153,7 @@ module Teckel
153
153
  #
154
154
  # Explicit call-time settings will *not* get merged with declared default setting.
155
155
  #
156
- # @param settings [Hash{String,Symbol => Object}] Set settings for a step by it's name
156
+ # @param settings [Hash{(String,Symbol) => Object}] Set settings for a step by it's name
157
157
  #
158
158
  # @example
159
159
  # class MyOperation
@@ -188,15 +188,18 @@ module Teckel
188
188
  # result = Chain.with(a: { other: "What" }).call
189
189
  # result.success #=> {say: nil, other: "What"}
190
190
  def default_settings!(settings) # :nodoc: The bang is for consistency with the Operation class
191
- @config.for(:default_settings, settings)
191
+ @config.get_or_set(:default_settings, settings)
192
192
  end
193
193
 
194
194
  # Getter for configured default settings
195
- # @return [nil|#call] The callable constructor
195
+ # @return [NilClass]
196
+ # @return [#call] The callable constructor
196
197
  def default_settings
197
- @config.for(:default_settings)
198
+ @config.get_or_set(:default_settings)
198
199
  end
199
200
 
201
+ # @!visibility private
202
+ # @return [Array<Symbol>]
200
203
  REQUIRED_CONFIGS = %i[around runner result result_constructor].freeze
201
204
 
202
205
  # @!visibility private
@@ -227,7 +230,7 @@ module Teckel
227
230
  # @return [self]
228
231
  # @!visibility public
229
232
  def dup
230
- dup_config(super())
233
+ dup_config(super()) # standard:disable Style/SuperArguments
231
234
  end
232
235
 
233
236
  # Produces a clone of this chain.
@@ -237,9 +240,9 @@ module Teckel
237
240
  # @!visibility public
238
241
  def clone
239
242
  if frozen?
240
- super()
243
+ super() # standard:disable Style/SuperArguments
241
244
  else
242
- dup_config(super())
245
+ dup_config(super()) # standard:disable Style/SuperArguments
243
246
  end
244
247
  end
245
248
 
@@ -250,7 +253,7 @@ module Teckel
250
253
  def freeze
251
254
  steps.freeze
252
255
  @config.freeze
253
- super()
256
+ super() # standard:disable Style/SuperArguments
254
257
  end
255
258
 
256
259
  # @!visibility private
@@ -263,9 +266,7 @@ module Teckel
263
266
  base.instance_variable_set(:@config, Teckel::Config.new)
264
267
  end
265
268
 
266
- private
267
-
268
- def dup_config(other_class)
269
+ private def dup_config(other_class)
269
270
  new_config = @config.dup
270
271
  new_config.replace(:steps) { steps.dup }
271
272
 
@@ -273,7 +274,7 @@ module Teckel
273
274
  other_class
274
275
  end
275
276
 
276
- def build_constructor(on, sym_or_proc)
277
+ private def build_constructor(on, sym_or_proc)
277
278
  case sym_or_proc
278
279
  when Proc
279
280
  sym_or_proc
@@ -1,12 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
4
-
5
3
  module Teckel
6
4
  module Chain
7
5
  class Result < Teckel::Operation::Result
8
- extend Forwardable
9
-
10
6
  # @param value [Object] The result value
11
7
  # @param success [Boolean] whether this is a successful result
12
8
  # @param step [Teckel::Chain::Step]
@@ -16,13 +12,13 @@ module Teckel
16
12
  end
17
13
 
18
14
  class << self
19
- alias :[] :new
15
+ alias_method :[], :new
20
16
  end
21
17
 
22
- # @!method step
23
- # Delegates to +step.name+
24
- # @return [String,Symbol] The step name of the failed operation.
25
- def_delegator :@step, :name, :step
18
+ # @return [String,Symbol] The step name of the failed operation.
19
+ def step
20
+ @step.name
21
+ end
26
22
 
27
23
  def deconstruct
28
24
  [successful?, @step.name, value]
@@ -7,9 +7,13 @@ module Teckel
7
7
  # @!visibility protected
8
8
  class Runner
9
9
  # @!visibility private
10
- UNDEFINED = Object.new
10
+ # @return [Object]
11
+ UNDEFINED = Teckel::UNDEFINED
11
12
 
12
13
  # @!visibility private
14
+ # @attr [Object] value the return value / result of the step execution
15
+ # @attr [Boolean] success whether the step has been executed successfully
16
+ # @attr [Teckel::Chain::Step] the step instance
13
17
  StepResult = Struct.new(:value, :success, :step)
14
18
 
15
19
  def initialize(chain, settings = UNDEFINED)
@@ -32,9 +36,7 @@ module Teckel
32
36
  settings.eql?(UNDEFINED) ? chain.steps : steps_with_settings
33
37
  end
34
38
 
35
- private
36
-
37
- def run(input)
39
+ private def run(input)
38
40
  steps.each_with_object(StepResult.new(input)) do |step, step_result|
39
41
  result = step.operation.call(step_result.value)
40
42
 
@@ -46,11 +48,11 @@ module Teckel
46
48
  end
47
49
  end
48
50
 
49
- def step_with_settings(step)
51
+ private def step_with_settings(step)
50
52
  settings.key?(step.name) ? step.with(settings[step.name]) : step
51
53
  end
52
54
 
53
- def steps_with_settings
55
+ private def steps_with_settings
54
56
  Enumerator.new do |yielder|
55
57
  chain.steps.each do |step|
56
58
  yielder << step_with_settings(step)
data/lib/teckel/chain.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'chain/config'
4
- require_relative 'chain/step'
5
- require_relative 'chain/result'
6
- require_relative 'chain/runner'
3
+ require_relative "chain/config"
4
+ require_relative "chain/step"
5
+ require_relative "chain/result"
6
+ require_relative "chain/runner"
7
7
 
8
8
  module Teckel
9
9
  # Railway style execution of multiple Operations.
@@ -45,13 +45,13 @@ module Teckel
45
45
  # @return [Teckel::Chain::Result] The result object wrapping
46
46
  # the result value, the success state and last executed step.
47
47
  def call(input = nil)
48
- default_settings = self.default_settings
48
+ default_settings = default_settings()
49
49
 
50
50
  runner =
51
51
  if default_settings
52
- self.runner.new(self, default_settings)
52
+ runner().new(self, default_settings)
53
53
  else
54
- self.runner.new(self)
54
+ runner().new(self)
55
55
  end
56
56
 
57
57
  if around
@@ -61,16 +61,20 @@ module Teckel
61
61
  end
62
62
  end
63
63
 
64
- # @param settings [Hash{String,Symbol => Object}] Set settings for a step by it's name
64
+ # Provide settings to the configured steps.
65
+ #
66
+ # @param settings [Hash{(String,Symbol) => Object}] Set settings for a step by it's name
67
+ # @return [#call] A callable, either a {Teckel::Chain::Runner} or,
68
+ # when configured with an around hook, a +Proc+
65
69
  def with(settings)
66
- runner = self.runner.new(self, settings)
70
+ runner = runner().new(self, settings)
67
71
  if around
68
- ->(input) { around.call(runner, input) }
72
+ around.curry[runner]
69
73
  else
70
74
  runner
71
75
  end
72
76
  end
73
- alias :set :with
77
+ alias_method :set, :with
74
78
  end
75
79
 
76
80
  def self.included(receiver)
data/lib/teckel/config.rb CHANGED
@@ -15,11 +15,16 @@ module Teckel
15
15
  # - sets (and returns) the blocks return value otherwise
16
16
  # - calling without +value+ and +block+ works like {Hash#[]}
17
17
  #
18
+ # @param key [Symbol,String] Name of the configuration
19
+ # @param value [Object] Value of the configuration
20
+ # @yield [key] If using in fetch mode and no value has been set
21
+ # @yieldparam key [Symbol,String] Name of the configuration
22
+ # @return [Object]
18
23
  # @raise [FrozenConfigError] When overwriting a key
19
24
  # @!visibility private
20
- def for(key, value = nil, &block)
25
+ def get_or_set(key, value = nil, &block)
21
26
  if value.nil?
22
- get_or_set(key, &block)
27
+ _get_or_set(key, &block)
23
28
  elsif @config.key?(key)
24
29
  raise FrozenConfigError, "Configuration #{key} is already set"
25
30
  else
@@ -28,6 +33,9 @@ module Teckel
28
33
  end
29
34
 
30
35
  # @!visibility private
36
+ # @param key [Symbol,String] Name of the configuration
37
+ # @yieldreturn [Object] The new setting
38
+ # @return [Object,nil] The new setting or +nil+ if not replaced
31
39
  def replace(key)
32
40
  @config[key] = yield if @config.key?(key)
33
41
  end
@@ -35,19 +43,17 @@ module Teckel
35
43
  # @!visibility private
36
44
  def freeze
37
45
  @config.freeze
38
- super()
46
+ super() # standard:disable Style/SuperArguments
39
47
  end
40
48
 
41
49
  # @!visibility private
42
50
  def dup
43
- super().tap do |copy|
44
- copy.instance_variable_set(:@config, @config.dup)
45
- end
51
+ copy = super() # standard:disable Style/SuperArguments
52
+ copy.instance_variable_set(:@config, @config.dup)
53
+ copy
46
54
  end
47
55
 
48
- private
49
-
50
- def get_or_set(key, &block)
56
+ private def _get_or_set(key, &block)
51
57
  if block
52
58
  @config[key] ||= @config.fetch(key, &block)
53
59
  else
@@ -5,14 +5,14 @@ module Teckel
5
5
  # Simple contract for enforcing data to be not set or +nil+
6
6
  module None
7
7
  class << self
8
- # Always return nil
9
- # @return nil
8
+ # Always return +nil+
9
+ # @return [NilClass]
10
10
  # @raise [ArgumentError] when called with any non-nil arguments
11
11
  def [](*args)
12
12
  raise ArgumentError, "None called with arguments" if args.any?(&:itself)
13
13
  end
14
14
 
15
- alias :new :[]
15
+ alias_method :new, :[]
16
16
  end
17
17
  end
18
18
  end
@@ -11,7 +11,7 @@ module Teckel
11
11
  # @param klass [Class] The +input+ class
12
12
  # @return [Class] The +input+ class
13
13
  def input(klass = nil)
14
- @config.for(:input, klass) { self::Input if const_defined?(:Input) } ||
14
+ @config.get_or_set(:input, klass) { self::Input if const_defined?(:Input) } ||
15
15
  raise(MissingConfigError, "Missing input config for #{self}")
16
16
  end
17
17
 
@@ -57,7 +57,7 @@ module Teckel
57
57
  #
58
58
  # MyOperation.input_constructor.is_a?(Proc) #=> true
59
59
  def input_constructor(sym_or_proc = nil)
60
- get_set_constructor(:input_constructor, input, sym_or_proc)
60
+ get_or_set_constructor(:input_constructor, input, sym_or_proc)
61
61
  end
62
62
 
63
63
  # @overload output()
@@ -70,7 +70,7 @@ module Teckel
70
70
  # @param klass [Class] The +output+ class
71
71
  # @return [Class] The +output+ class
72
72
  def output(klass = nil)
73
- @config.for(:output, klass) { self::Output if const_defined?(:Output) } ||
73
+ @config.get_or_set(:output, klass) { self::Output if const_defined?(:Output) } ||
74
74
  raise(MissingConfigError, "Missing output config for #{self}")
75
75
  end
76
76
 
@@ -102,7 +102,7 @@ module Teckel
102
102
  # output_constructor ->(name, options) { Output.new(name: name, **options) }
103
103
  # end
104
104
  def output_constructor(sym_or_proc = nil)
105
- get_set_constructor(:output_constructor, output, sym_or_proc)
105
+ get_or_set_constructor(:output_constructor, output, sym_or_proc)
106
106
  end
107
107
 
108
108
  # @overload error()
@@ -114,7 +114,7 @@ module Teckel
114
114
  # @param klass [Class] The +error+ class
115
115
  # @return [Class,nil] The +error+ class or +nil+ if it does not error
116
116
  def error(klass = nil)
117
- @config.for(:error, klass) { self::Error if const_defined?(:Error) } ||
117
+ @config.get_or_set(:error, klass) { self::Error if const_defined?(:Error) } ||
118
118
  raise(MissingConfigError, "Missing error config for #{self}")
119
119
  end
120
120
 
@@ -146,7 +146,7 @@ module Teckel
146
146
  # error_constructor ->(name, options) { Error.new(name: name, **options) }
147
147
  # end
148
148
  def error_constructor(sym_or_proc = nil)
149
- get_set_constructor(:error_constructor, error, sym_or_proc)
149
+ get_or_set_constructor(:error_constructor, error, sym_or_proc)
150
150
  end
151
151
 
152
152
  # @!endgroup
@@ -160,7 +160,7 @@ module Teckel
160
160
  # @param klass [Class] The +settings+ class
161
161
  # @return [Class] The +settings+ class configured
162
162
  def settings(klass = nil)
163
- @config.for(:settings, klass) { const_defined?(:Settings) ? self::Settings : none }
163
+ @config.get_or_set(:settings, klass) { const_defined?(:Settings) ? self::Settings : none }
164
164
  end
165
165
 
166
166
  # @overload settings_constructor()
@@ -187,7 +187,7 @@ module Teckel
187
187
  # settings_constructor :new
188
188
  # end
189
189
  def settings_constructor(sym_or_proc = nil)
190
- get_set_constructor(:settings_constructor, settings, sym_or_proc) ||
190
+ get_or_set_constructor(:settings_constructor, settings, sym_or_proc) ||
191
191
  raise(MissingConfigError, "Missing settings_constructor config for #{self}")
192
192
  end
193
193
 
@@ -222,13 +222,14 @@ module Teckel
222
222
 
223
223
  callable ||= -> { settings_constructor.call(*args) }
224
224
 
225
- @config.for(:default_settings, callable)
225
+ @config.get_or_set(:default_settings, callable)
226
226
  end
227
227
 
228
228
  # Getter for configured default settings
229
- # @return [nil|#call] The callable constructor
229
+ # @return [NilClass]
230
+ # @return [#call] The callable constructor
230
231
  def default_settings
231
- @config.for(:default_settings)
232
+ @config.get_or_set(:default_settings)
232
233
  end
233
234
 
234
235
  # @overload runner()
@@ -240,12 +241,12 @@ module Teckel
240
241
  # @param klass [Class] A class like the {Runner}
241
242
  # @!visibility protected
242
243
  def runner(klass = nil)
243
- @config.for(:runner, klass) { Runner }
244
+ @config.get_or_set(:runner, klass) { Runner }
244
245
  end
245
246
 
246
247
  # @overload result()
247
248
  # Get the configured result object class wrapping {error} or {output}.
248
- # The {ValueResult} default will act as a pass-through and does. Any error
249
+ # The {ValueResult} default will act as a pass-through. Any error
249
250
  # or output will just returned as-is.
250
251
  # @return [Class] The +result+ class, or {ValueResult} as default
251
252
  #
@@ -254,9 +255,12 @@ module Teckel
254
255
  # @param klass [Class] The +result+ class
255
256
  # @return [Class] The +result+ class configured
256
257
  def result(klass = nil)
257
- @config.for(:result, klass) { const_defined?(:Result, false) ? self::Result : ValueResult }
258
+ @config.get_or_set(:result, klass) { const_defined?(:Result, false) ? self::Result : ValueResult }
258
259
  end
259
260
 
261
+ # @param sym_or_proc [Symbol,Proc,NilClass]
262
+ # @return [#call]
263
+ #
260
264
  # @overload result_constructor()
261
265
  # The callable constructor to build an instance of the +result+ class.
262
266
  # Defaults to {Teckel::DEFAULT_CONSTRUCTOR}
@@ -282,7 +286,7 @@ module Teckel
282
286
  # result_constructor ->(value, success) { result.new(value, success, {foo: :bar}) }
283
287
  # end
284
288
  def result_constructor(sym_or_proc = nil)
285
- get_set_constructor(:result_constructor, result, sym_or_proc) ||
289
+ get_or_set_constructor(:result_constructor, result, sym_or_proc) ||
286
290
  raise(MissingConfigError, "Missing result_constructor config for #{self}")
287
291
  end
288
292
 
@@ -293,14 +297,15 @@ module Teckel
293
297
  #
294
298
  # @!visibility protected
295
299
  # @note Don't use in conjunction with {result} or {result_constructor}
296
- # @return [nil]
300
+ # @return [void]
297
301
  def result!
298
- @config.for(:result, Result)
299
- @config.for(:result_constructor, Result.method(:new))
302
+ @config.get_or_set(:result, Result)
303
+ @config.get_or_set(:result_constructor, Result.method(:new))
300
304
  nil
301
305
  end
302
306
 
303
307
  # @!visibility private
308
+ # @return [Array<Symbol>]
304
309
  REQUIRED_CONFIGS = %i[
305
310
  input input_constructor
306
311
  output output_constructor
@@ -334,7 +339,7 @@ module Teckel
334
339
  # @return [self]
335
340
  # @!visibility public
336
341
  def dup
337
- dup_config(super())
342
+ dup_config(super()) # standard:disable Style/SuperArguments
338
343
  end
339
344
 
340
345
  # Produces a clone of this operation and all it's configuration
@@ -343,9 +348,9 @@ module Teckel
343
348
  # @!visibility public
344
349
  def clone
345
350
  if frozen?
346
- super()
351
+ super() # standard:disable Style/SuperArguments
347
352
  else
348
- dup_config(super())
353
+ dup_config(super()) # standard:disable Style/SuperArguments
349
354
  end
350
355
  end
351
356
 
@@ -355,7 +360,7 @@ module Teckel
355
360
  # @!visibility public
356
361
  def freeze
357
362
  @config.freeze
358
- super()
363
+ super() # standard:disable Style/SuperArguments
359
364
  end
360
365
 
361
366
  # @!visibility private
@@ -372,22 +377,20 @@ module Teckel
372
377
  end
373
378
  end
374
379
 
375
- private
376
-
377
- def dup_config(other_class)
380
+ private def dup_config(other_class)
378
381
  other_class.instance_variable_set(:@config, @config.dup)
379
382
  other_class
380
383
  end
381
384
 
382
- def get_set_constructor(name, on, sym_or_proc)
385
+ private def get_or_set_constructor(name, on, sym_or_proc)
383
386
  constructor = build_constructor(on, sym_or_proc)
384
387
 
385
- @config.for(name, constructor) {
388
+ @config.get_or_set(name, constructor) {
386
389
  build_constructor(on, DEFAULT_CONSTRUCTOR)
387
390
  }
388
391
  end
389
392
 
390
- def build_constructor(on, sym_or_proc)
393
+ private def build_constructor(on, sym_or_proc)
391
394
  case sym_or_proc
392
395
  when Proc
393
396
  sym_or_proc