servactory 3.0.0 → 3.1.0.rc2

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/servactory/actions/action.rb +2 -2
  3. data/lib/servactory/actions/collection.rb +1 -1
  4. data/lib/servactory/actions/stages/collection.rb +1 -1
  5. data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +60 -2
  6. data/lib/servactory/context/warehouse/inputs.rb +2 -2
  7. data/lib/servactory/context/workspace/inputs.rb +22 -10
  8. data/lib/servactory/context/workspace/internals.rb +35 -13
  9. data/lib/servactory/context/workspace/outputs.rb +12 -6
  10. data/lib/servactory/dsl.rb +1 -1
  11. data/lib/servactory/info/builder.rb +2 -3
  12. data/lib/servactory/inputs/collection.rb +14 -21
  13. data/lib/servactory/inputs/input.rb +6 -103
  14. data/lib/servactory/inputs/tools/validation.rb +32 -57
  15. data/lib/servactory/inputs/validations/required.rb +3 -2
  16. data/lib/servactory/internals/collection.rb +5 -24
  17. data/lib/servactory/internals/internal.rb +4 -112
  18. data/lib/servactory/maintenance/attributes/base.rb +135 -0
  19. data/lib/servactory/maintenance/attributes/collection.rb +109 -0
  20. data/lib/servactory/maintenance/attributes/option_helper.rb +33 -12
  21. data/lib/servactory/maintenance/{attributes/options_collection.rb → options/collection.rb} +6 -7
  22. data/lib/servactory/maintenance/{attributes → options}/define_conflict.rb +1 -1
  23. data/lib/servactory/maintenance/{attributes → options}/define_method.rb +1 -1
  24. data/lib/servactory/maintenance/options/helper.rb +23 -0
  25. data/lib/servactory/maintenance/{attributes → options}/option.rb +50 -27
  26. data/lib/servactory/maintenance/options/registrar.rb +200 -0
  27. data/lib/servactory/maintenance/{attributes/validations → validations/checkers}/must.rb +25 -8
  28. data/lib/servactory/maintenance/{attributes/validations → validations/checkers}/type.rb +6 -5
  29. data/lib/servactory/maintenance/validations/concerns/error_builder.rb +50 -0
  30. data/lib/servactory/maintenance/validations/performer.rb +57 -0
  31. data/lib/servactory/maintenance/validations/support/type_validator.rb +36 -0
  32. data/lib/servactory/maintenance/{attributes → validations}/translator/must.rb +1 -1
  33. data/lib/servactory/maintenance/{attributes → validations}/translator/type.rb +1 -1
  34. data/lib/servactory/outputs/collection.rb +5 -24
  35. data/lib/servactory/outputs/output.rb +4 -112
  36. data/lib/servactory/result.rb +12 -18
  37. data/lib/servactory/tool_kit/dynamic_options/must.rb +2 -2
  38. data/lib/servactory/tool_kit/dynamic_options/schema.rb +5 -5
  39. data/lib/servactory/utils.rb +0 -8
  40. data/lib/servactory/version.rb +2 -2
  41. metadata +16 -13
  42. data/lib/servactory/maintenance/attributes/options/registrar.rb +0 -183
  43. data/lib/servactory/maintenance/attributes/tools/validation.rb +0 -84
  44. data/lib/servactory/maintenance/attributes/validations/concerns/error_builder.rb +0 -52
  45. data/lib/servactory/maintenance/validations/types.rb +0 -34
@@ -3,81 +3,56 @@
3
3
  module Servactory
4
4
  module Inputs
5
5
  module Tools
6
- class Validation
7
- def self.validate!(...)
8
- new(...).validate!
9
- end
10
-
11
- def initialize(context, collection_of_inputs)
12
- @context = context
13
- @collection_of_inputs = collection_of_inputs
14
- @first_error = nil
15
- end
16
-
17
- def validate!
18
- @collection_of_inputs.each do |input|
19
- process_input(input)
20
- break if @first_error.present?
6
+ module Validation
7
+ extend self
8
+
9
+ def validate!(context, collection_of_inputs) # rubocop:disable Metrics/MethodLength
10
+ warehouse = context.send(:servactory_service_warehouse)
11
+ first_error = nil
12
+ failed_input = nil
13
+
14
+ collection_of_inputs.each do |input|
15
+ first_error = process_input(context, warehouse, input)
16
+ if first_error.present?
17
+ failed_input = input
18
+ break
19
+ end
21
20
  end
22
21
 
23
- raise_errors
22
+ return if first_error.nil?
23
+
24
+ context.fail_input!(failed_input.name, message: first_error)
24
25
  end
25
26
 
26
27
  private
27
28
 
28
- def process_input(input)
29
+ def process_input(context, warehouse, input)
30
+ value = warehouse.fetch_input(input.name)
31
+
29
32
  input.options_for_checks.each do |check_key, check_options|
30
- process_option(check_key, check_options, input:)
31
- break if @first_error.present?
33
+ error = process_option(context, input, value, check_key, check_options)
34
+ return error if error.present?
32
35
  end
36
+
37
+ nil
33
38
  end
34
39
 
35
- def process_option(check_key, check_options, input:) # rubocop:disable Metrics/MethodLength
36
- validation_classes = validation_classes_from(input)
40
+ def process_option(context, input, value, check_key, check_options) # rubocop:disable Metrics/MethodLength
41
+ validation_classes = input.collection_of_options.validation_classes
37
42
  return if validation_classes.empty?
38
43
 
39
44
  validation_classes.each do |validation_class|
40
- error_message = process_validation_class(
41
- validation_class:,
42
- input:,
45
+ error_message = validation_class.check(
46
+ context:,
47
+ attribute: input,
48
+ value:,
43
49
  check_key:,
44
50
  check_options:
45
51
  )
46
-
47
- next if error_message.blank?
48
-
49
- @first_error = error_message
50
- break
52
+ return error_message if error_message.present?
51
53
  end
52
- end
53
-
54
- def process_validation_class(
55
- validation_class:,
56
- input:,
57
- check_key:,
58
- check_options:
59
- )
60
- validation_class.check(
61
- context: @context,
62
- attribute: input,
63
- value: @context.send(:servactory_service_warehouse).fetch_input(input.name),
64
- check_key:,
65
- check_options:
66
- )
67
- end
68
-
69
- ########################################################################
70
-
71
- def validation_classes_from(input)
72
- @validation_classes_cache ||= input.collection_of_options.validation_classes # rubocop:disable Naming/MemoizedInstanceVariableName
73
- end
74
-
75
- ########################################################################
76
-
77
- def raise_errors
78
- return if @first_error.nil?
79
54
 
80
- @context.fail_input!(nil, message: @first_error)
55
+ nil
81
56
  end
82
57
  end
83
58
  end
@@ -22,7 +22,7 @@ module Servactory
22
22
  # end
23
23
  # ```
24
24
  class Required
25
- extend Servactory::Maintenance::Attributes::Validations::Concerns::ErrorBuilder
25
+ extend Servactory::Maintenance::Validations::Concerns::ErrorBuilder
26
26
 
27
27
  # Validates that a required input has a present value.
28
28
  #
@@ -30,8 +30,9 @@ module Servactory
30
30
  # @param attribute [Inputs::Input] Input attribute to validate
31
31
  # @param value [Object] Value to check for presence
32
32
  # @param check_key [Symbol] Must be :required to trigger validation
33
+ # @param check_options [Hash, nil] Unused, accepted for uniform checker interface
33
34
  # @return [String, nil] Error message on failure, nil on success
34
- def self.check(context:, attribute:, value:, check_key:, **)
35
+ def self.check(context:, attribute:, value:, check_key:, check_options: nil) # rubocop:disable Lint/UnusedMethodArgument
35
36
  return unless should_be_checked_for?(attribute, check_key)
36
37
  return if Servactory::Utils.value_present?(value)
37
38
 
@@ -2,30 +2,11 @@
2
2
 
3
3
  module Servactory
4
4
  module Internals
5
- class Collection
6
- extend Forwardable
7
-
8
- def_delegators :@collection, :<<, :filter, :each, :map, :to_h, :merge, :find
9
-
10
- def initialize(collection = Set.new)
11
- @collection = collection
12
- end
13
-
14
- def only(*names)
15
- Collection.new(filter { |internal| names.include?(internal.name) })
16
- end
17
-
18
- def except(*names)
19
- Collection.new(filter { |internal| names.exclude?(internal.name) })
20
- end
21
-
22
- def names
23
- map(&:name)
24
- end
25
-
26
- def find_by(name:)
27
- find { |internal| internal.name == name }
28
- end
5
+ # Specialized collection for Internal attributes.
6
+ #
7
+ # Inherits all behavior from the base Attributes::Collection
8
+ # without any overrides.
9
+ class Collection < Servactory::Maintenance::Attributes::Collection
29
10
  end
30
11
  end
31
12
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module Internals
5
- class Internal
5
+ class Internal < Servactory::Maintenance::Attributes::Base
6
6
  class Actor
7
7
  attr_reader :name,
8
8
  :types,
@@ -26,138 +26,30 @@ module Servactory
26
26
  # The methods below are required to support the internal work.
27
27
 
28
28
  def input?
29
- false
29
+ @attribute.input?
30
30
  end
31
31
 
32
32
  def internal?
33
- true
33
+ @attribute.internal?
34
34
  end
35
35
 
36
36
  def output?
37
- false
37
+ @attribute.output?
38
38
  end
39
39
  end
40
40
 
41
- attr_reader :name,
42
- :collection_of_options,
43
- :options
44
-
45
- def initialize(
46
- name,
47
- *helpers,
48
- option_helpers:,
49
- **options
50
- )
51
- @name = name
52
- @option_helpers = option_helpers
53
-
54
- register_options(helpers:, options:)
55
- end
56
-
57
- def method_missing(name, *args, &block)
58
- option = @collection_of_options.find_by(name:)
59
- return super if option.nil?
60
-
61
- option.body
62
- end
63
-
64
- def respond_to_missing?(name, *)
65
- @collection_of_options.names.include?(name) || super
66
- end
67
-
68
- def register_options(helpers:, options:)
69
- merged_options = augment_options_with_helpers(helpers:, options:)
70
- options_registrar = create_options_registrar(options: merged_options)
71
-
72
- @options = merged_options
73
- @collection_of_options = options_registrar.collection
74
- end
75
-
76
- def options_for_checks
77
- @collection_of_options.options_for_checks
78
- end
79
-
80
- def system_name
81
- self.class.name.demodulize.downcase.to_sym
82
- end
83
-
84
- def i18n_name
85
- system_name.to_s.pluralize
86
- end
87
-
88
- def input?
89
- false
90
- end
91
-
92
41
  def internal?
93
42
  true
94
43
  end
95
44
 
96
- def output?
97
- false
98
- end
99
-
100
45
  private
101
46
 
102
- def create_options_registrar(options:)
103
- Servactory::Maintenance::Attributes::Options::Registrar.register(
104
- attribute: self,
105
- options:,
106
- features: available_feature_options
107
- )
108
- end
109
-
110
47
  def available_feature_options
111
48
  {
112
49
  types: true,
113
50
  must: true
114
51
  }
115
52
  end
116
-
117
- def augment_options_with_helpers(helpers:, options:)
118
- result_options = options.dup
119
- merge_standard_helpers_into(target_options: result_options, helpers:) if helpers.present?
120
- merge_advanced_helpers_into(target_options: result_options, source_options: options)
121
- result_options
122
- end
123
-
124
- def merge_standard_helpers_into(target_options:, helpers:)
125
- standard_helpers_result = transform_helpers_to_options(helpers:)
126
- target_options.deep_merge!(standard_helpers_result)
127
- end
128
-
129
- def merge_advanced_helpers_into(target_options:, source_options:)
130
- advanced_helpers = filter_advanced_helpers(options: source_options)
131
- return if advanced_helpers.blank?
132
-
133
- advanced_helpers_result = transform_helpers_to_options(helpers: advanced_helpers)
134
- target_options.deep_merge!(advanced_helpers_result)
135
- end
136
-
137
- def filter_advanced_helpers(options:)
138
- reserved_options = Servactory::Maintenance::Attributes::Options::Registrar::RESERVED_OPTIONS
139
- options.except(*reserved_options)
140
- end
141
-
142
- def transform_helpers_to_options(helpers:)
143
- helpers.each_with_object({}) do |(helper_name, values), result|
144
- helper = @option_helpers.find_by(name: helper_name)
145
- next if helper.blank?
146
-
147
- transformed_option = transform_helper_to_option(helper:, values:)
148
- result.deep_merge!(transformed_option) if transformed_option.present?
149
- end
150
- end
151
-
152
- def transform_helper_to_option(helper:, values:)
153
- return helper.equivalent unless helper.equivalent.is_a?(Proc)
154
-
155
- if values.is_a?(Hash)
156
- helper.equivalent.call(**values)
157
- else
158
- helper.equivalent.call(values)
159
- end
160
- end
161
53
  end
162
54
  end
163
55
  end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class Base
7
+ attr_reader :name,
8
+ :collection_of_options,
9
+ :options
10
+
11
+ def initialize(
12
+ name,
13
+ *helpers,
14
+ option_helpers:,
15
+ **options
16
+ )
17
+ @name = name
18
+ @option_helpers = option_helpers
19
+
20
+ register_options(helpers:, options:)
21
+ end
22
+
23
+ def method_missing(name, *args, &block)
24
+ option = @collection_of_options.find_by(name:)
25
+ return super if option.nil?
26
+
27
+ option.body_for_access
28
+ end
29
+
30
+ def respond_to_missing?(name, *)
31
+ @collection_of_options.names.include?(name) || super
32
+ end
33
+
34
+ def register_options(helpers:, options:)
35
+ merged_options = augment_options_with_helpers(helpers:, options:)
36
+ options_registrar = create_options_registrar(options: merged_options)
37
+
38
+ @options = merged_options
39
+ @collection_of_options = options_registrar.collection
40
+ end
41
+
42
+ def options_for_checks
43
+ @collection_of_options.options_for_checks
44
+ end
45
+
46
+ def system_name
47
+ @system_name ||= self.class.name.demodulize.downcase.to_sym
48
+ end
49
+
50
+ def i18n_name
51
+ @i18n_name ||= system_name.to_s.pluralize
52
+ end
53
+
54
+ def actor
55
+ @actor ||= self.class::Actor.new(self)
56
+ end
57
+
58
+ def typed_actor_kwargs
59
+ @typed_actor_kwargs ||= { system_name => actor }.freeze
60
+ end
61
+
62
+ def input?
63
+ false
64
+ end
65
+
66
+ def internal?
67
+ false
68
+ end
69
+
70
+ def output?
71
+ false
72
+ end
73
+
74
+ private
75
+
76
+ def create_options_registrar(options:)
77
+ Servactory::Maintenance::Options::Registrar.register(
78
+ attribute: self,
79
+ options:,
80
+ features: available_feature_options
81
+ )
82
+ end
83
+
84
+ def available_feature_options
85
+ raise NotImplementedError, "Subclass must implement available_feature_options"
86
+ end
87
+
88
+ def augment_options_with_helpers(helpers:, options:)
89
+ result_options = options.dup
90
+ merge_standard_helpers_into(target_options: result_options, helpers:) if helpers.present?
91
+ merge_advanced_helpers_into(target_options: result_options, source_options: options)
92
+ result_options
93
+ end
94
+
95
+ def merge_standard_helpers_into(target_options:, helpers:)
96
+ standard_helpers_result = transform_helpers_to_options(helpers:)
97
+ target_options.deep_merge!(standard_helpers_result)
98
+ end
99
+
100
+ def merge_advanced_helpers_into(target_options:, source_options:)
101
+ advanced_helpers = filter_advanced_helpers(options: source_options)
102
+ return if advanced_helpers.blank?
103
+
104
+ advanced_helpers_result = transform_helpers_to_options(helpers: advanced_helpers)
105
+ target_options.deep_merge!(advanced_helpers_result)
106
+ end
107
+
108
+ def filter_advanced_helpers(options:)
109
+ reserved_options = Servactory::Maintenance::Options::Registrar::RESERVED_OPTIONS
110
+ options.except(*reserved_options)
111
+ end
112
+
113
+ def transform_helpers_to_options(helpers:)
114
+ helpers.each_with_object({}) do |(helper_name, values), result|
115
+ helper = @option_helpers.find_by(name: helper_name)
116
+ next if helper.blank?
117
+
118
+ transformed_option = transform_helper_to_option(helper:, values:)
119
+ result.deep_merge!(transformed_option) if transformed_option.present?
120
+ end
121
+ end
122
+
123
+ def transform_helper_to_option(helper:, values:)
124
+ return helper.equivalent unless helper.equivalent.is_a?(Proc)
125
+
126
+ if values.is_a?(Hash)
127
+ helper.equivalent.call(**values)
128
+ else
129
+ helper.equivalent.call(values)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ # Collection wrapper for managing attribute objects (inputs, internals, outputs).
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # Collection provides a polymorphic base for storing and querying attribute
11
+ # instances. It wraps a Set to ensure uniqueness and delegates common
12
+ # enumeration methods. Subclasses override `lookup_name` to customize
13
+ # how attributes are indexed and filtered (e.g., inputs use `internal_name`
14
+ # for the `as:` parameter).
15
+ #
16
+ # ## Usage
17
+ #
18
+ # Subclasses are used internally by Input, Internal, and Output DSL modules
19
+ # to manage their registered attributes:
20
+ #
21
+ # ```ruby
22
+ # collection = Collection.new
23
+ # collection << attribute
24
+ #
25
+ # collection.names # => [:first_name, :last_name]
26
+ # collection.find_by(name: :first_name) # => attribute instance
27
+ # collection.only(:first_name) # => filtered Collection
28
+ # collection.except(:last_name) # => filtered Collection
29
+ # ```
30
+ #
31
+ # ## Performance
32
+ #
33
+ # The collection uses memoization for frequently accessed data:
34
+ # - `attributes_index` - cached hash for O(1) lookups by name
35
+ #
36
+ class Collection
37
+ extend Forwardable
38
+
39
+ def_delegators :@collection,
40
+ :<<,
41
+ :filter,
42
+ :each, :each_with_object,
43
+ :map, :to_h,
44
+ :merge
45
+
46
+ # Initializes the collection with an optional pre-built Set.
47
+ #
48
+ # @param collection [Set] initial set of attributes
49
+ # @return [Collection]
50
+ def initialize(collection = Set.new)
51
+ @collection = collection
52
+ end
53
+
54
+ # Returns names of all attributes in the collection.
55
+ #
56
+ # @return [Array<Symbol>] list of attribute names
57
+ def names
58
+ map(&:name)
59
+ end
60
+
61
+ # Returns a new collection containing only the named attributes.
62
+ #
63
+ # @param names [Array<Symbol>] attribute names to include
64
+ # @return [Collection] filtered collection
65
+ def only(*names)
66
+ self.class.new(filter { |attribute| names.include?(lookup_name(attribute)) })
67
+ end
68
+
69
+ # Returns a new collection excluding the named attributes.
70
+ #
71
+ # @param names [Array<Symbol>] attribute names to exclude
72
+ # @return [Collection] filtered collection
73
+ def except(*names)
74
+ self.class.new(filter { |attribute| names.exclude?(lookup_name(attribute)) })
75
+ end
76
+
77
+ # Finds an attribute by its name using indexed lookup.
78
+ #
79
+ # @param name [Symbol] the attribute name to find
80
+ # @return [Object, nil] the found attribute or nil
81
+ def find_by(name:)
82
+ attributes_index[name]
83
+ end
84
+
85
+ private
86
+
87
+ # Builds and caches a hash index for O(1) attribute lookups.
88
+ #
89
+ # @return [Hash{Symbol => Object}] attribute names mapped to attribute instances
90
+ def attributes_index
91
+ @attributes_index ||= each_with_object({}) do |attribute, index|
92
+ index[lookup_name(attribute)] = attribute
93
+ end
94
+ end
95
+
96
+ # Returns the name used for indexing and filtering a given attribute.
97
+ #
98
+ # Subclasses override this to use alternative name fields
99
+ # (e.g., `internal_name` for inputs with the `as:` parameter).
100
+ #
101
+ # @param attribute [Object] the attribute to extract a name from
102
+ # @return [Symbol] the lookup name
103
+ def lookup_name(attribute)
104
+ attribute.name
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -3,19 +3,40 @@
3
3
  module Servactory
4
4
  module Maintenance
5
5
  module Attributes
6
- class OptionHelper
7
- attr_reader :name,
8
- :equivalent,
9
- :meta
10
-
6
+ # @deprecated Use {Servactory::Maintenance::Options::Helper} instead.
7
+ # This class is maintained for backward compatibility only and will be
8
+ # removed in a future major version.
9
+ #
10
+ # OptionHelper provides a simple way to define custom option helpers
11
+ # for service inputs, internals, and outputs configuration.
12
+ #
13
+ # @example Creating a custom option helper
14
+ # Servactory::Maintenance::Attributes::OptionHelper.new(
15
+ # name: :must_be_positive,
16
+ # equivalent: {
17
+ # must: {
18
+ # be_positive: {
19
+ # is: ->(value:, **) { value.positive? },
20
+ # message: "must be positive"
21
+ # }
22
+ # }
23
+ # }
24
+ # )
25
+ #
26
+ # @see Servactory::Maintenance::Options::Helper The new preferred class
27
+ class OptionHelper < Servactory::Maintenance::Options::Helper
28
+ # @deprecated This class is deprecated. Use Options::Helper instead.
29
+ #
30
+ # Creates a new OptionHelper instance.
31
+ #
32
+ # @param name [Symbol] The name of the option helper
33
+ # @param equivalent [Hash, Proc] The equivalent option configuration
34
+ # @param meta [Hash] Additional metadata for the helper
35
+ # @return [OptionHelper] A new instance
11
36
  def initialize(name:, equivalent:, meta: {})
12
- @name = name
13
- @equivalent = equivalent
14
- @meta = meta
15
- end
16
-
17
- def dynamic_option?
18
- meta[:type] == :dynamic_option
37
+ warn "[DEPRECATION] Servactory::Maintenance::Attributes::OptionHelper is deprecated. " \
38
+ "Use Servactory::Maintenance::Options::Helper instead."
39
+ super
19
40
  end
20
41
  end
21
42
  end
@@ -2,12 +2,12 @@
2
2
 
3
3
  module Servactory
4
4
  module Maintenance
5
- module Attributes
5
+ module Options
6
6
  # Collection wrapper for managing Option objects.
7
7
  #
8
8
  # ## Purpose
9
9
  #
10
- # OptionsCollection provides a unified interface for storing and querying
10
+ # Collection provides a unified interface for storing and querying
11
11
  # Option instances associated with service attributes (inputs, internals, outputs).
12
12
  # It wraps a Set to ensure uniqueness and delegates common enumeration methods.
13
13
  #
@@ -17,7 +17,7 @@ module Servactory
17
17
  # to manage their registered options:
18
18
  #
19
19
  # ```ruby
20
- # collection = OptionsCollection.new
20
+ # collection = Collection.new
21
21
  # collection << Option.new(name: :required, ...)
22
22
  # collection << Option.new(name: :types, ...)
23
23
  #
@@ -32,21 +32,20 @@ module Servactory
32
32
  # - `options_for_checks` - cached hash for validation pipeline
33
33
  # - `options_index` - cached hash for O(1) lookups by name
34
34
  #
35
- class OptionsCollection
35
+ class Collection
36
36
  extend Forwardable
37
37
 
38
38
  def_delegators :@collection,
39
39
  :<<,
40
40
  :filter,
41
- :each, :each_with_object,
41
+ :each_with_object,
42
42
  :map, :flat_map,
43
- :find,
44
43
  :size,
45
44
  :empty?
46
45
 
47
46
  # Initializes an empty collection.
48
47
  #
49
- # @return [OptionsCollection]
48
+ # @return [Collection]
50
49
  def initialize
51
50
  @collection = Set.new
52
51
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module Maintenance
5
- module Attributes
5
+ module Options
6
6
  class DefineConflict
7
7
  attr_reader :content
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module Maintenance
5
- module Attributes
5
+ module Options
6
6
  class DefineMethod
7
7
  attr_reader :name,
8
8
  :content