servactory 3.0.0.rc3 → 3.0.0.rc4

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/lib/servactory/context/warehouse/base.rb +20 -4
  3. data/lib/servactory/context/warehouse/crate.rb +39 -0
  4. data/lib/servactory/context/warehouse/inputs.rb +41 -10
  5. data/lib/servactory/context/warehouse/internals.rb +7 -2
  6. data/lib/servactory/context/warehouse/outputs.rb +7 -0
  7. data/lib/servactory/context/warehouse/setup.rb +53 -30
  8. data/lib/servactory/context/workspace/inputs.rb +6 -8
  9. data/lib/servactory/context/workspace/internals.rb +5 -7
  10. data/lib/servactory/context/workspace/outputs.rb +5 -7
  11. data/lib/servactory/inputs/input.rb +28 -18
  12. data/lib/servactory/inputs/tools/validation.rb +9 -9
  13. data/lib/servactory/inputs/validations/required.rb +51 -27
  14. data/lib/servactory/internals/internal.rb +20 -16
  15. data/lib/servactory/maintenance/attributes/tools/validation.rb +9 -10
  16. data/lib/servactory/maintenance/attributes/validations/concerns/error_builder.rb +52 -0
  17. data/lib/servactory/maintenance/attributes/validations/must.rb +164 -57
  18. data/lib/servactory/maintenance/attributes/validations/type.rb +77 -27
  19. data/lib/servactory/maintenance/validations/types.rb +18 -33
  20. data/lib/servactory/outputs/output.rb +18 -13
  21. data/lib/servactory/result.rb +266 -43
  22. data/lib/servactory/version.rb +1 -1
  23. metadata +3 -6
  24. data/lib/servactory/inputs/validations/base.rb +0 -21
  25. data/lib/servactory/inputs/validations/errors.rb +0 -17
  26. data/lib/servactory/maintenance/attributes/tools/check_errors.rb +0 -23
  27. data/lib/servactory/maintenance/attributes/validations/base.rb +0 -23
  28. data/lib/servactory/maintenance/attributes/validations/errors.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5972f03405d88ae923f1e000479449e281af67b9d22b52010d2131dc1023cc15
4
- data.tar.gz: 6c7c495d158deee0453114fb637897a2431d7ce4efc4e522a0716ec28a7dd89b
3
+ metadata.gz: 4c94166cc0d29f50acac299374f644be29db0b4ee533ca49c7f9e0ec698c32a6
4
+ data.tar.gz: 022a3b05c74fbef3005fd6ec7cc09b9d3b8459d5544578bc09731e9d8378f2e5
5
5
  SHA512:
6
- metadata.gz: 82e84edd70b3ee47a91944bd60e5d9bec1cf33b18ca5d008d40973685c796cfa31b48de2f0599764c864db535959cd86a073ed30725c1fe1af49a98ce4bd72ab
7
- data.tar.gz: 585a53ba4491246e5e4aaec23568e074a2d142d467b9d44bc551d629bce2047fcfd99d89c0bdcb897e9a28e9f7037b9128396107fe6c01083ff0b4298ee11f71
6
+ metadata.gz: f411d897f5885d6b783c9b5531c6ae1b71d0b681b8249d635bf8e6152613bb43630f6705674f33cb54351daa9f207352fb2ab23b488629a05a5bfc4a44329e01
7
+ data.tar.gz: db0bd759b7e7da5c50a3283b144a8ba8ba1a58ce6fa3fd7c91709e46adcaa661fce2103d03fe2e70a59ba37906f984c8c4944bf54d54aa00a8832b76552e7b83
@@ -3,19 +3,35 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Warehouse
6
+ # Base class for warehouse storage views.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Provides common fetch and assign operations for all warehouse
11
+ # view classes (Inputs, Internals, Outputs).
6
12
  class Base
13
+ # Creates base view with storage hash reference.
14
+ #
15
+ # @param arguments [Hash] Reference to Crate data
16
+ # @return [Base] New base view
7
17
  def initialize(arguments = {})
8
18
  @arguments = arguments
9
19
  end
10
20
 
11
- # def fetch!(name)
12
- # @arguments.fetch(name)
13
- # end
14
-
21
+ # Retrieves value by name with default fallback.
22
+ #
23
+ # @param name [Symbol] Key name
24
+ # @param default_value [Object] Value if not found
25
+ # @return [Object] Stored or default value
15
26
  def fetch(name, default_value)
16
27
  @arguments.fetch(name, default_value)
17
28
  end
18
29
 
30
+ # Stores value by key.
31
+ #
32
+ # @param key [Symbol] Key name
33
+ # @param value [Object] Value to store
34
+ # @return [Object] Stored value
19
35
  def assign(key, value)
20
36
  @arguments[key] = value
21
37
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Context
5
+ module Warehouse
6
+ # Unified crate for service context data.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Crate provides a single object that holds all three data sections
11
+ # (inputs, internals, outputs) in separate hashes. This reduces object
12
+ # allocations compared to creating separate warehouse instances.
13
+ #
14
+ # ## Usage
15
+ #
16
+ # Crate is used internally by Setup class:
17
+ #
18
+ # ```ruby
19
+ # crate = Crate.new
20
+ # crate.inputs[:name] = "value"
21
+ # crate.outputs[:result] = result
22
+ # ```
23
+ class Crate
24
+ attr_reader :inputs,
25
+ :internals,
26
+ :outputs
27
+
28
+ # Creates new crate with empty sections.
29
+ #
30
+ # @return [Crate] New crate instance
31
+ def initialize
32
+ @inputs = {}
33
+ @internals = {}
34
+ @outputs = {}
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,41 +3,72 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Warehouse
6
+ # View for accessing service input values.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Inputs provides access to service input data with dynamic method access,
11
+ # predicate support, and error handling. It references Crate data
12
+ # instead of creating its own.
6
13
  class Inputs < Base
7
- def initialize(context, arguments = {})
14
+ # Creates inputs view referencing Crate data.
15
+ #
16
+ # @param context [Object] Service context for error handling
17
+ # @param arguments [Hash] Reference to Crate#inputs
18
+ # @return [Inputs] New inputs view
19
+ def initialize(context, arguments)
8
20
  @context = context
9
21
 
10
22
  super(arguments)
11
23
  end
12
24
 
25
+ # Returns array of input names.
26
+ #
27
+ # @return [Array<Symbol>] Input names
13
28
  def names
14
29
  @arguments.keys
15
30
  end
16
31
 
32
+ # Merges new arguments into storage.
33
+ #
34
+ # @param arguments [Hash] Input name-value pairs to merge
35
+ # @return [Hash] Updated arguments hash
17
36
  def merge!(arguments)
18
37
  @arguments.merge!(arguments)
19
38
  end
20
39
 
21
- ##########################################################################
22
-
40
+ # Delegates method calls to stored inputs.
41
+ #
42
+ # Supports predicate methods when enabled in config.
43
+ #
44
+ # @param name [Symbol] Method name (input or predicate)
45
+ # @param _args [Array] Method arguments (unused)
46
+ # @return [Object] Input value or predicate result
23
47
  def method_missing(name, *_args)
24
- input_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
48
+ predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
49
+
50
+ input_name = predicate ? name.to_s.chomp("?").to_sym : name
25
51
 
26
52
  input_value = @arguments.fetch(input_name) { raise_error_for(input_name) }
27
53
 
28
- if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
29
- Servactory::Utils.query_attribute(input_value)
30
- else
31
- input_value
32
- end
54
+ predicate ? Servactory::Utils.query_attribute(input_value) : input_value
33
55
  end
34
56
 
57
+ # Checks if method corresponds to stored input.
58
+ #
59
+ # @param name [Symbol] Method name to check
60
+ # @param _include_private [Boolean] Include private methods in check
61
+ # @return [Boolean] True if input exists for this method
35
62
  def respond_to_missing?(name, *)
36
63
  @arguments.fetch(name) { raise_error_for(name) }
37
64
  end
38
65
 
39
- ##########################################################################
66
+ private
40
67
 
68
+ # Raises error for undefined input.
69
+ #
70
+ # @param input_name [Symbol] Name of undefined input
71
+ # @raise [Exception] Failure exception with localized message
41
72
  def raise_error_for(input_name)
42
73
  message_text = @context.send(:servactory_service_info).translate(
43
74
  "inputs.undefined.for_fetch",
@@ -3,8 +3,13 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Warehouse
6
- class Internals < Base
7
- end
6
+ # View for accessing service internal values.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Internals provides simple key-value storage for intermediate
11
+ # service state. It references Crate data.
12
+ class Internals < Base; end
8
13
  end
9
14
  end
10
15
  end
@@ -3,6 +3,13 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Warehouse
6
+ # View for accessing service output values.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Outputs provides storage for service result values with iteration
11
+ # support via each_pair delegation. Used by Result class to build
12
+ # output hash.
6
13
  class Outputs < Base
7
14
  extend Forwardable
8
15
 
@@ -3,69 +3,92 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Warehouse
6
+ # Orchestrator for service context data.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Setup manages a unified Crate instance and provides the public
11
+ # interface for accessing inputs, internals, and outputs. It creates
12
+ # view objects lazily on first access.
6
13
  class Setup
14
+ # Creates setup with unified crate.
15
+ #
16
+ # @param context [Object] Service context
17
+ # @return [Setup] New setup instance
7
18
  def initialize(context)
8
19
  @context = context
20
+ @crate = Crate.new
9
21
  end
10
22
 
23
+ # Merges input arguments into storage.
24
+ #
25
+ # @param arguments [Hash] Input name-value pairs
26
+ # @return [Hash] Updated inputs hash
11
27
  def assign_inputs(arguments)
12
- context_data[:inputs].merge!(arguments)
28
+ inputs.merge!(arguments)
13
29
  end
14
30
 
31
+ # Retrieves input value by name.
32
+ #
33
+ # @param name [Symbol] Input name
34
+ # @return [Object, nil] Input value or nil
15
35
  def fetch_input(name)
16
36
  inputs.fetch(name, nil)
17
37
  end
18
38
 
39
+ # Stores internal value by name.
40
+ #
41
+ # @param name [Symbol] Internal name
42
+ # @param value [Object] Value to store
43
+ # @return [Object] Stored value
19
44
  def assign_internal(name, value)
20
- assign_attribute(:internals, name, value)
45
+ internals.assign(name, value)
21
46
  end
22
47
 
48
+ # Retrieves internal value by name.
49
+ #
50
+ # @param name [Symbol] Internal name
51
+ # @return [Object, nil] Internal value or nil
23
52
  def fetch_internal(name)
24
53
  internals.fetch(name, nil)
25
54
  end
26
55
 
56
+ # Stores output value by name.
57
+ #
58
+ # @param name [Symbol] Output name
59
+ # @param value [Object] Value to store
60
+ # @return [Object] Stored value
27
61
  def assign_output(name, value)
28
- assign_attribute(:outputs, name, value)
62
+ outputs.assign(name, value)
29
63
  end
30
64
 
65
+ # Retrieves output value by name.
66
+ #
67
+ # @param name [Symbol] Output name
68
+ # @return [Object, nil] Output value or nil
31
69
  def fetch_output(name)
32
70
  outputs.fetch(name, nil)
33
71
  end
34
72
 
73
+ # Returns inputs view object.
74
+ #
75
+ # @return [Inputs] Inputs view
35
76
  def inputs
36
- @inputs ||= context_data.fetch(:inputs)
77
+ @inputs ||= Inputs.new(@context, @crate.inputs)
37
78
  end
38
79
 
80
+ # Returns internals view object.
81
+ #
82
+ # @return [Internals] Internals view
39
83
  def internals
40
- @internals ||= context_data.fetch(:internals)
84
+ @internals ||= Internals.new(@crate.internals)
41
85
  end
42
86
 
87
+ # Returns outputs view object.
88
+ #
89
+ # @return [Outputs] Outputs view
43
90
  def outputs
44
- @outputs ||= context_data.fetch(:outputs)
45
- end
46
-
47
- private
48
-
49
- def assign_attribute(section, name, value)
50
- context_data[section].assign(name, value)
51
- end
52
-
53
- def context_data
54
- @context_data ||= state.fetch(context_id)
55
- end
56
-
57
- def state
58
- {
59
- context_id => {
60
- inputs: Servactory::Context::Warehouse::Inputs.new(@context),
61
- internals: Servactory::Context::Warehouse::Internals.new,
62
- outputs: Servactory::Context::Warehouse::Outputs.new
63
- }
64
- }
65
- end
66
-
67
- def context_id
68
- @context_id ||= "context_#{@context.object_id}"
91
+ @outputs ||= Outputs.new(@crate.outputs)
69
92
  end
70
93
  end
71
94
  end
@@ -39,7 +39,9 @@ module Servactory
39
39
 
40
40
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Lint/UnusedMethodArgument
41
41
  def fetch_with(name:, &block)
42
- input_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
42
+ predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
43
+
44
+ input_name = predicate ? name.to_s.chomp("?").to_sym : name
43
45
 
44
46
  input = @collection_of_inputs.find_by(name: input_name)
45
47
 
@@ -51,14 +53,10 @@ module Servactory
51
53
  input_value = input.default
52
54
  end
53
55
 
54
- input_prepare = input.prepare.fetch(:in, nil)
55
- input_value = input_prepare.call(value: input_value) if input_prepare.present?
56
+ input_prepare = input.prepare[:in]
57
+ input_value = input_prepare.call(value: input_value) if input_prepare
56
58
 
57
- if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
58
- Servactory::Utils.query_attribute(input_value)
59
- else
60
- input_value
61
- end
59
+ predicate ? Servactory::Utils.query_attribute(input_value) : input_value
62
60
  end
63
61
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Lint/UnusedMethodArgument
64
62
 
@@ -53,8 +53,10 @@ module Servactory
53
53
  @context.send(:servactory_service_warehouse).assign_internal(internal.name, value)
54
54
  end
55
55
 
56
- def fetch_with(name:, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Lint/UnusedMethodArgument
57
- internal_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
56
+ def fetch_with(name:, &block) # rubocop:disable Metrics/MethodLength, Lint/UnusedMethodArgument
57
+ predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
58
+
59
+ internal_name = predicate ? name.to_s.chomp("?").to_sym : name
58
60
  internal = @collection_of_internals.find_by(name: internal_name)
59
61
 
60
62
  return yield if internal.nil?
@@ -67,11 +69,7 @@ module Servactory
67
69
  value: internal_value
68
70
  )
69
71
 
70
- if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
71
- Servactory::Utils.query_attribute(internal_value)
72
- else
73
- internal_value
74
- end
72
+ predicate ? Servactory::Utils.query_attribute(internal_value) : internal_value
75
73
  end
76
74
 
77
75
  def raise_error_for(type, name)
@@ -53,19 +53,17 @@ module Servactory
53
53
  @context.send(:servactory_service_warehouse).assign_output(output.name, value)
54
54
  end
55
55
 
56
- def fetch_with(name:, &block) # rubocop:disable Metrics/AbcSize, Lint/UnusedMethodArgument
57
- output_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
56
+ def fetch_with(name:, &block) # rubocop:disable Lint/UnusedMethodArgument
57
+ predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
58
+
59
+ output_name = predicate ? name.to_s.chomp("?").to_sym : name
58
60
  output = @collection_of_outputs.find_by(name: output_name)
59
61
 
60
62
  return yield if output.nil?
61
63
 
62
64
  output_value = @context.send(:servactory_service_warehouse).fetch_output(output.name)
63
65
 
64
- if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
65
- Servactory::Utils.query_attribute(output_value)
66
- else
67
- output_value
68
- end
66
+ predicate ? Servactory::Utils.query_attribute(output_value) : output_value
69
67
  end
70
68
 
71
69
  def raise_error_for(type, name)
@@ -16,27 +16,37 @@ module Servactory
16
16
  @types = input.types
17
17
  @default = input.default
18
18
  @options = input.options
19
+ @attribute = input
20
+ end
21
+
22
+ def system_name
23
+ @attribute.system_name
24
+ end
25
+
26
+ def i18n_name
27
+ @attribute.i18n_name
28
+ end
29
+
30
+ def optional?
31
+ @attribute.optional?
32
+ end
33
+
34
+ def required?
35
+ @attribute.required?
36
+ end
37
+
38
+ # The methods below are required to support the internal work.
39
+
40
+ def input?
41
+ true
42
+ end
19
43
 
20
- define_identity_methods(input)
44
+ def internal?
45
+ false
21
46
  end
22
47
 
23
- private
24
-
25
- def define_identity_methods(input) # rubocop:disable Metrics/MethodLength
26
- methods_map = {
27
- system_name: -> { input.system_name },
28
- i18n_name: -> { input.i18n_name },
29
- optional?: -> { input.optional? },
30
- required?: -> { input.required? },
31
- # The methods below are required to support the internal work.
32
- input?: -> { true },
33
- internal?: -> { false },
34
- output?: -> { false }
35
- }
36
-
37
- methods_map.each do |method_name, implementation|
38
- define_singleton_method(method_name, &implementation)
39
- end
48
+ def output?
49
+ false
40
50
  end
41
51
  end
42
52
 
@@ -11,11 +11,13 @@ module Servactory
11
11
  def initialize(context, collection_of_inputs)
12
12
  @context = context
13
13
  @collection_of_inputs = collection_of_inputs
14
+ @first_error = nil
14
15
  end
15
16
 
16
17
  def validate!
17
18
  @collection_of_inputs.each do |input|
18
19
  process_input(input)
20
+ break if @first_error.present?
19
21
  end
20
22
 
21
23
  raise_errors
@@ -26,6 +28,7 @@ module Servactory
26
28
  def process_input(input)
27
29
  input.options_for_checks.each do |check_key, check_options|
28
30
  process_option(check_key, check_options, input:)
31
+ break if @first_error.present?
29
32
  end
30
33
  end
31
34
 
@@ -34,16 +37,17 @@ module Servactory
34
37
  return if validation_classes.empty?
35
38
 
36
39
  validation_classes.each do |validation_class|
37
- errors_from_checks = process_validation_class(
40
+ error_message = process_validation_class(
38
41
  validation_class:,
39
42
  input:,
40
43
  check_key:,
41
44
  check_options:
42
45
  )
43
46
 
44
- next if errors_from_checks.nil? || errors_from_checks.empty?
47
+ next if error_message.blank?
45
48
 
46
- errors.merge(errors_from_checks.to_a)
49
+ @first_error = error_message
50
+ break
47
51
  end
48
52
  end
49
53
 
@@ -70,14 +74,10 @@ module Servactory
70
74
 
71
75
  ########################################################################
72
76
 
73
- def errors
74
- @errors ||= Servactory::Maintenance::Attributes::Tools::CheckErrors.new
75
- end
76
-
77
77
  def raise_errors
78
- return if (tmp_errors = errors.not_blank).empty?
78
+ return if @first_error.nil?
79
79
 
80
- @context.fail_input!(nil, message: tmp_errors.first)
80
+ @context.fail_input!(nil, message: @first_error)
81
81
  end
82
82
  end
83
83
  end
@@ -3,45 +3,69 @@
3
3
  module Servactory
4
4
  module Inputs
5
5
  module Validations
6
- class Required < Base
6
+ # Validates that required inputs have non-empty values.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Required validator ensures that inputs marked as `required: true`
11
+ # have meaningful values. It checks for presence using `value_present?`
12
+ # which handles nil, empty strings, and blank values.
13
+ #
14
+ # ## Usage
15
+ #
16
+ # This validator is automatically applied to inputs with `required: true`:
17
+ #
18
+ # ```ruby
19
+ # class MyService < ApplicationService::Base
20
+ # input :email, type: String, required: true
21
+ # input :name, type: String, required: { message: "Name is mandatory" }
22
+ # end
23
+ # ```
24
+ class Required
25
+ extend Servactory::Maintenance::Attributes::Validations::Concerns::ErrorBuilder
26
+
27
+ # Validates that a required input has a present value.
28
+ #
29
+ # @param context [Object] Service context for error message formatting
30
+ # @param attribute [Inputs::Input] Input attribute to validate
31
+ # @param value [Object] Value to check for presence
32
+ # @param check_key [Symbol] Must be :required to trigger validation
33
+ # @return [String, nil] Error message on failure, nil on success
7
34
  def self.check(context:, attribute:, value:, check_key:, **)
8
35
  return unless should_be_checked_for?(attribute, check_key)
36
+ return if Servactory::Utils.value_present?(value)
9
37
 
10
- new(context:, input: attribute, value:).check
38
+ build_error_message(context:, input: attribute, value:)
11
39
  end
12
40
 
41
+ # Determines if validation should run for given input and check key.
42
+ #
43
+ # @param input [Inputs::Input] Input to check
44
+ # @param check_key [Symbol] Current validation check key
45
+ # @return [Boolean] true if this validator should run
13
46
  def self.should_be_checked_for?(input, check_key)
14
47
  check_key == :required && input.required?
15
48
  end
49
+ private_class_method :should_be_checked_for?
16
50
 
17
- ##########################################################################
18
-
19
- def initialize(context:, input:, value:)
20
- super()
21
-
22
- @context = context
23
- @input = input
24
- @value = value
25
- end
26
-
27
- def check
28
- return if Servactory::Utils.value_present?(@value)
29
-
30
- _, message = @input.required.values_at(:is, :message)
31
-
32
- add_error_with(message)
33
- end
34
-
35
- private
51
+ # Builds error message from validation failure.
52
+ #
53
+ # @param context [Object] Service context
54
+ # @param input [Inputs::Input] Input that failed validation
55
+ # @param value [Object] The invalid value
56
+ # @return [String] Processed error message
57
+ def self.build_error_message(context:, input:, value:)
58
+ _, message = input.required.values_at(:is, :message)
59
+ message = message.presence || Servactory::Inputs::Translator::Required.default_message
36
60
 
37
- def add_error_with(message)
38
- add_error(
39
- message: message.presence || Servactory::Inputs::Translator::Required.default_message,
40
- service: @context.send(:servactory_service_info),
41
- input: @input,
42
- value: @value
61
+ process_message(
62
+ message,
63
+ service: context.send(:servactory_service_info),
64
+ input:,
65
+ value:
43
66
  )
44
67
  end
68
+ private_class_method :build_error_message
45
69
  end
46
70
  end
47
71
  end
@@ -12,25 +12,29 @@ module Servactory
12
12
  @name = internal.name
13
13
  @types = internal.types
14
14
  @options = internal.options
15
+ @attribute = internal
16
+ end
17
+
18
+ def system_name
19
+ @attribute.system_name
20
+ end
21
+
22
+ def i18n_name
23
+ @attribute.i18n_name
24
+ end
25
+
26
+ # The methods below are required to support the internal work.
27
+
28
+ def input?
29
+ false
30
+ end
15
31
 
16
- define_identity_methods(internal)
32
+ def internal?
33
+ true
17
34
  end
18
35
 
19
- private
20
-
21
- def define_identity_methods(internal)
22
- methods_map = {
23
- system_name: -> { internal.system_name },
24
- i18n_name: -> { internal.i18n_name },
25
- # The methods below are required to support the internal work.
26
- input?: -> { false },
27
- internal?: -> { true },
28
- output?: -> { false }
29
- }
30
-
31
- methods_map.each do |method_name, implementation|
32
- define_singleton_method(method_name, &implementation)
33
- end
36
+ def output?
37
+ false
34
38
  end
35
39
  end
36
40