domainic-attributer 0.1.0 → 0.2.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.md +32 -1
  4. data/README.md +42 -355
  5. data/docs/USAGE.md +723 -0
  6. data/lib/domainic/attributer/attribute/callback.rb +21 -9
  7. data/lib/domainic/attributer/attribute/coercer.rb +28 -13
  8. data/lib/domainic/attributer/attribute/mixin/belongs_to_attribute.rb +16 -13
  9. data/lib/domainic/attributer/attribute/signature.rb +43 -32
  10. data/lib/domainic/attributer/attribute/validator.rb +46 -16
  11. data/lib/domainic/attributer/attribute.rb +28 -18
  12. data/lib/domainic/attributer/attribute_set.rb +21 -19
  13. data/lib/domainic/attributer/class_methods.rb +136 -83
  14. data/lib/domainic/attributer/dsl/attribute_builder/option_parser.rb +64 -22
  15. data/lib/domainic/attributer/dsl/attribute_builder.rb +515 -26
  16. data/lib/domainic/attributer/dsl/initializer.rb +23 -18
  17. data/lib/domainic/attributer/dsl/method_injector.rb +16 -14
  18. data/lib/domainic/attributer/errors/aggregate_error.rb +36 -0
  19. data/lib/domainic/attributer/errors/callback_execution_error.rb +30 -0
  20. data/lib/domainic/attributer/errors/coercion_execution_error.rb +37 -0
  21. data/lib/domainic/attributer/errors/error.rb +19 -0
  22. data/lib/domainic/attributer/errors/validation_execution_error.rb +30 -0
  23. data/lib/domainic/attributer/instance_methods.rb +11 -8
  24. data/lib/domainic/attributer/undefined.rb +9 -7
  25. data/lib/domainic/attributer.rb +88 -27
  26. data/sig/domainic/attributer/attribute/callback.rbs +10 -7
  27. data/sig/domainic/attributer/attribute/coercer.rbs +14 -11
  28. data/sig/domainic/attributer/attribute/mixin/belongs_to_attribute.rbs +14 -12
  29. data/sig/domainic/attributer/attribute/signature.rbs +43 -32
  30. data/sig/domainic/attributer/attribute/validator.rbs +28 -13
  31. data/sig/domainic/attributer/attribute.rbs +27 -17
  32. data/sig/domainic/attributer/attribute_set.rbs +21 -19
  33. data/sig/domainic/attributer/class_methods.rbs +133 -80
  34. data/sig/domainic/attributer/dsl/attribute_builder/option_parser.rbs +62 -22
  35. data/sig/domainic/attributer/dsl/attribute_builder.rbs +515 -26
  36. data/sig/domainic/attributer/dsl/initializer.rbs +21 -19
  37. data/sig/domainic/attributer/dsl/method_injector.rbs +16 -14
  38. data/sig/domainic/attributer/errors/aggregate_error.rbs +28 -0
  39. data/sig/domainic/attributer/errors/callback_execution_error.rbs +23 -0
  40. data/sig/domainic/attributer/errors/coercion_execution_error.rbs +29 -0
  41. data/sig/domainic/attributer/errors/error.rbs +17 -0
  42. data/sig/domainic/attributer/errors/validation_execution_error.rbs +23 -0
  43. data/sig/domainic/attributer/instance_methods.rbs +11 -8
  44. data/sig/domainic/attributer/undefined.rbs +5 -3
  45. data/sig/domainic/attributer.rbs +88 -27
  46. metadata +19 -6
@@ -1,15 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'domainic/attributer/undefined'
4
+
3
5
  module Domainic
4
6
  module Attributer
5
7
  module DSL
6
- # A class responsible for handling object initialization with attributes.
8
+ # A class responsible for handling object initialization with attributes
7
9
  #
8
10
  # This class manages the process of setting attribute values during object
9
11
  # initialization. It handles both positional arguments and keyword options,
10
12
  # applying them to their corresponding attributes while respecting default
11
- # values and required attributes.
13
+ # values and required attributes
12
14
  #
15
+ # @api private
16
+ # @!visibility private
13
17
  # @author {https://aaronmallen.me Aaron Allen}
14
18
  # @since 0.1.0
15
19
  class Initializer
@@ -18,25 +22,25 @@ module Domainic
18
22
  # @rbs @base: Object
19
23
  # @rbs @option_attributes: Array[Attribute]
20
24
 
21
- # Initialize a new Initializer.
25
+ # Initialize a new Initializer
22
26
  #
23
27
  # @param base [Object] the instance being initialized
24
28
  #
25
- # @return [void]
29
+ # @return [Initializer] the new Initializer instance
26
30
  # @rbs (Object base) -> void
27
31
  def initialize(base)
28
32
  @base = base
29
33
  @attributes ||= @base.class.send(:__attributes__)
30
34
  end
31
35
 
32
- # Assign values to attributes.
36
+ # Assign values to attributes
33
37
  #
34
38
  # Validates and applies both positional arguments and keyword options to
35
39
  # their corresponding attributes. Raises an error if required arguments
36
- # are missing.
40
+ # are missing
37
41
  #
38
- # @param arguments [Array] positional arguments to assign
39
- # @param keyword_arguments [Hash] keyword arguments to assign
42
+ # @param arguments [Array<Object>] positional arguments to assign
43
+ # @param keyword_arguments [Hash{Symbol => Object}] keyword arguments to assign
40
44
  #
41
45
  # @raise [ArgumentError] if required arguments are missing
42
46
  # @return [void]
@@ -49,14 +53,14 @@ module Domainic
49
53
 
50
54
  private
51
55
 
52
- # Access to the current attribute set.
56
+ # Access to the current attribute set
53
57
  #
54
58
  # @return [AttributeSet] the attribute set for this instance
55
59
  attr_reader :attributes #: AttributeSet
56
60
 
57
- # Apply positional arguments to their attributes.
61
+ # Apply positional arguments to their attributes
58
62
  #
59
- # @param arguments [Array] the positional arguments to apply
63
+ # @param arguments [Array<Object>] the positional arguments to apply
60
64
  #
61
65
  # @return [void]
62
66
  # @rbs (Array[untyped]) -> void
@@ -67,9 +71,9 @@ module Domainic
67
71
  end
68
72
  end
69
73
 
70
- # Apply keyword arguments to their attributes.
74
+ # Apply keyword arguments to their attributes
71
75
  #
72
- # @param options [Hash] the keyword options to apply
76
+ # @param options [Hash{Symbol => Object}] the keyword options to apply
73
77
  #
74
78
  # @return [void]
75
79
  # @rbs (Hash[String | Symbol, untyped]) -> void
@@ -85,7 +89,7 @@ module Domainic
85
89
  end
86
90
  end
87
91
 
88
- # Get all argument attributes.
92
+ # Get all argument attributes
89
93
  #
90
94
  # @return [Array<Attribute>] the argument attributes
91
95
  # @rbs () -> Array[Attribute]
@@ -93,17 +97,18 @@ module Domainic
93
97
  @argument_attributes ||= attributes.select { |_, attribute| attribute.signature.argument? }.attributes
94
98
  end
95
99
 
96
- # Assign a value to an attribute.
100
+ # Assign a value to an attribute
97
101
  #
98
102
  # @param attribute_name [Symbol] the name of the attribute
99
103
  # @param value [Object] the value to assign
100
104
  #
101
105
  # @return [void]
106
+ # @rbs (String | Symbol attribute_name, untyped value) -> void
102
107
  def assign_value(attribute_name, value)
103
108
  @base.send(:"#{attribute_name}=", value)
104
109
  end
105
110
 
106
- # Get all option attributes.
111
+ # Get all option attributes
107
112
  #
108
113
  # @return [Array<Attribute>] the option attributes
109
114
  # @rbs () -> Array[Attribute]
@@ -111,9 +116,9 @@ module Domainic
111
116
  @option_attributes ||= attributes.select { |_, attribute| attribute.signature.option? }.attributes
112
117
  end
113
118
 
114
- # Validate that all required positional arguments are provided.
119
+ # Validate that all required positional arguments are provided
115
120
  #
116
- # @param arguments [Array] the arguments to validate
121
+ # @param arguments [Array<Object>] the arguments to validate
117
122
  #
118
123
  # @raise [ArgumentError] if required arguments are missing
119
124
  # @return [void]
@@ -3,23 +3,25 @@
3
3
  module Domainic
4
4
  module Attributer
5
5
  module DSL
6
- # A class responsible for injecting attribute methods into classes.
6
+ # A class responsible for injecting attribute methods into classes
7
7
  #
8
8
  # This class handles the creation of reader and writer methods for attributes,
9
9
  # ensuring they are injected safely without overwriting existing methods. It
10
10
  # respects visibility settings and properly handles value assignment through
11
- # the attribute system.
11
+ # the attribute system
12
12
  #
13
+ # @api private
14
+ # @!visibility private
13
15
  # @author {https://aaronmallen.me Aaron Allen}
14
16
  # @since 0.1.0
15
17
  class MethodInjector
16
18
  # @rbs @attribute: Attribute
17
19
  # @rbs @base: __todo__
18
20
 
19
- # Inject methods for an attribute into a class.
21
+ # Inject methods for an attribute into a class
20
22
  #
21
23
  # @param base [Class, Module] the class to inject methods into
22
- # @param attribute [Attribute] the attribute to create methods for
24
+ # @param attribute [Attribute] the {Attribute} to create methods for
23
25
  #
24
26
  # @return [void]
25
27
  # @rbs (__todo__ base, Attribute attribute) -> void
@@ -27,19 +29,19 @@ module Domainic
27
29
  new(base, attribute).inject!
28
30
  end
29
31
 
30
- # Initialize a new MethodInjector.
32
+ # Initialize a new MethodInjector
31
33
  #
32
34
  # @param base [Class, Module] the class to inject methods into
33
- # @param attribute [Attribute] the attribute to create methods for
35
+ # @param attribute [Attribute] the {Attribute} to create methods for
34
36
  #
35
- # @return [void]
37
+ # @return [MethodInjector] the new MethodInjector instance
36
38
  # @rbs (__todo__ base, Attribute attribute) -> void
37
39
  def initialize(base, attribute)
38
40
  @attribute = attribute
39
41
  @base = base
40
42
  end
41
43
 
42
- # Inject reader and writer methods.
44
+ # Inject reader and writer methods
43
45
  #
44
46
  # @return [void]
45
47
  # @rbs () -> void
@@ -50,11 +52,11 @@ module Domainic
50
52
 
51
53
  private
52
54
 
53
- # Define a method if it doesn't already exist.
55
+ # Define a method if it doesn't already exist
54
56
  #
55
57
  # @param method_name [Symbol] the name of the method to define
56
- # @yield the method body to define
57
58
  #
59
+ # @yield the method body to define
58
60
  # @return [void]
59
61
  # @rbs (Symbol method_name) { (?) [self: untyped] -> void } -> void
60
62
  def define_safe_method(method_name, &)
@@ -63,9 +65,9 @@ module Domainic
63
65
  @base.define_method(method_name, &)
64
66
  end
65
67
 
66
- # Inject the attribute reader method.
68
+ # Inject the attribute reader method
67
69
  #
68
- # Creates a reader method with the configured visibility.
70
+ # Creates a reader method with the configured visibility
69
71
  #
70
72
  # @return [void]
71
73
  # @rbs () -> void
@@ -74,10 +76,10 @@ module Domainic
74
76
  @base.send(@attribute.signature.read_visibility, @attribute.name)
75
77
  end
76
78
 
77
- # Inject the attribute writer method.
79
+ # Inject the attribute writer method
78
80
  #
79
81
  # Creates a writer method that processes values through the attribute
80
- # system before assignment. Sets the configured visibility.
82
+ # system before assignment. Sets the configured visibility
81
83
  #
82
84
  # @return [void]
83
85
  # @rbs () -> void
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'domainic/attributer/errors/error'
4
+
5
+ module Domainic
6
+ module Attributer
7
+ # A specialized error class that combines multiple errors into a single error
8
+ #
9
+ # This class encapsulates multiple errors that occur during a single operation and
10
+ # need to be reported together. It maintains a list of individual errors while providing
11
+ # a formatted message that includes details from all errors
12
+ #
13
+ # @api private
14
+ # @!visibility private
15
+ # @author {https://aaronmallen.me Aaron Allen}
16
+ # @since 0.2.0
17
+ class AggregateError < Error
18
+ # Get the collection of errors that were aggregated
19
+ #
20
+ # @return [Array<StandardError>] the collection of errors
21
+ attr_reader :errors #: Array[StandardError]
22
+
23
+ # Initialize a new AggregateError instance
24
+ #
25
+ # @param message [String] the main error message
26
+ # @param errors [Array<StandardError>] the collection of errors to aggregate
27
+ #
28
+ # @return [AggregateError] the new AggregateError instance
29
+ # @rbs (String message, Array[StandardError] errors) -> void
30
+ def initialize(message, errors)
31
+ @errors = errors
32
+ super("#{message}\n#{errors.map { |error| " - #{error.message}" }.join("\n")}")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'domainic/attributer/errors/aggregate_error'
4
+
5
+ module Domainic
6
+ module Attributer
7
+ # A specialized error class for callback execution failures
8
+ #
9
+ # This error class is used when one or more callbacks fail during attribute value
10
+ # changes. It aggregates all callback-related errors into a single error with a
11
+ # descriptive message listing each individual failure
12
+ #
13
+ # @author {https://aaronmallen.me Aaron Allen}
14
+ # @since 0.2.0
15
+ class CallbackExecutionError < AggregateError
16
+ # Initialize a new CallbackExecutionError instance
17
+ #
18
+ # @api private
19
+ # @!visibility private
20
+ #
21
+ # @param errors [Array<StandardError>] the collection of callback errors to aggregate
22
+ #
23
+ # @return [CallbackExecutionError] the new CallbackExecutionError instance
24
+ # @rbs (Array[StandardError] errors) -> void
25
+ def initialize(errors)
26
+ super('The following errors occurred during callback execution:', errors)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'domainic/attributer/errors/error'
4
+
5
+ module Domainic
6
+ module Attributer
7
+ # A specialized error class for coercion execution failures
8
+ #
9
+ # This error class is used when a coercion fails during attribute value
10
+ # processing. It captures the failing coercer to provide context about which
11
+ # step in the coercion chain caused the failure
12
+ #
13
+ # @author {https://aaronmallen.me Aaron Allen}
14
+ # @since 0.2.0
15
+ class CoercionExecutionError < Error
16
+ # Get the coercer that failed
17
+ #
18
+ # @return [Proc, Symbol] the coercer that failed
19
+ attr_reader :coercer #: Attribute::Coercer::handler
20
+
21
+ # Initialize a new CoercionExecutionError instance
22
+ #
23
+ # @api private
24
+ # @!visibility private
25
+ #
26
+ # @param message [String] the error message
27
+ # @param coercer [Proc, Symbol] the coercer that failed
28
+ #
29
+ # @return [CoercionExecutionError] the new CoercionExecutionError instance
30
+ # @rbs (String message, Attribute::Coercer::handler coercer) -> void
31
+ def initialize(message, coercer)
32
+ @coercer = coercer
33
+ super(message)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Domainic
4
+ module Attributer
5
+ # Base error class for all Attributer-related errors
6
+ #
7
+ # This class serves as the foundation for Attributer's error hierarchy, allowing
8
+ # for specific error types to be caught and handled appropriately. All custom
9
+ # errors within the Attributer system should inherit from this class to maintain
10
+ # a consistent error handling pattern
11
+ #
12
+ # @api private
13
+ # @!visibility private
14
+ # @author {https://aaronmallen.me Aaron Allen}
15
+ # @since 0.2.0
16
+ class Error < StandardError
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'domainic/attributer/errors/aggregate_error'
4
+
5
+ module Domainic
6
+ module Attributer
7
+ # A specialized error class for validation execution failures
8
+ #
9
+ # This error class is used when one or more validations encounter errors during
10
+ # their execution. It aggregates all validation-related errors into a single
11
+ # error with a descriptive message listing each individual failure
12
+ #
13
+ # @author {https://aaronmallen.me Aaron Allen}
14
+ # @since 0.2.0
15
+ class ValidationExecutionError < AggregateError
16
+ # Initialize a new ValidationExecutionError instance
17
+ #
18
+ # @api private
19
+ # @!visibility private
20
+ #
21
+ # @param errors [Array<StandardError>] the collection of validation errors to aggregate
22
+ #
23
+ # @return [ValidationExecutionError] the new ValidationExecutionError instance
24
+ # @rbs (Array[StandardError] errors) -> void
25
+ def initialize(errors)
26
+ super('The following errors occurred during validation execution:', errors)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -4,11 +4,11 @@ require 'domainic/attributer/dsl/initializer'
4
4
 
5
5
  module Domainic
6
6
  module Attributer
7
- # A module providing instance-level attribute functionality.
7
+ # A module providing instance-level attribute functionality
8
8
  #
9
- # This module defines instance methods for objects that include Domainic::Attributer.
9
+ # This module defines instance methods for objects that include {Domainic::Attributer}.
10
10
  # It provides initialization handling and attribute serialization capabilities, making
11
- # it easy to work with attribute values in a consistent way.
11
+ # it easy to work with attribute values in a consistent way
12
12
  #
13
13
  # @example Basic usage
14
14
  # class Person
@@ -25,7 +25,7 @@ module Domainic
25
25
  # @author {https://aaronmallen.me Aaron Allen}
26
26
  # @since 0.1.0
27
27
  module InstanceMethods
28
- # Initialize a new instance with attribute values.
28
+ # Initialize a new instance with attribute values
29
29
  #
30
30
  # Handles both positional arguments and keyword options, applying them to their
31
31
  # corresponding attributes. This process includes:
@@ -34,20 +34,23 @@ module Domainic
34
34
  # 3. Type validation and coercion
35
35
  # 4. Change notifications
36
36
  #
37
+ # @example
38
+ # person = Person.new('Alice', age: 30)
39
+ #
37
40
  # @raise [ArgumentError] if required arguments are missing
38
- # @return [void]
41
+ # @return [InstanceMethods] the new InstanceMethods instance
39
42
  # @rbs (*untyped arguments, **untyped keyword_arguments) -> void
40
43
  def initialize(...)
41
44
  DSL::Initializer.new(self).assign!(...)
42
45
  end
43
46
 
44
- # Convert public attribute values to a hash.
47
+ # Convert public attribute values to a hash
45
48
  #
46
49
  # Creates a hash containing all public readable attributes and their current values.
47
50
  # Any attributes marked as private or protected for reading are excluded from
48
- # the result.
51
+ # the result
49
52
  #
50
- # @example Basic conversion
53
+ # @example
51
54
  # person = Person.new('Alice', age: 30)
52
55
  # person.to_h # => { name: 'Alice', age: 30 }
53
56
  #
@@ -2,38 +2,40 @@
2
2
 
3
3
  module Domainic
4
4
  module Attributer
5
- # A singleton object representing an undefined value.
5
+ # A singleton object representing an undefined value
6
6
  #
7
- # This object is used throughout Domainic::Attributer to represent values that
7
+ # This object is used throughout {Domainic::Attributer} to represent values that
8
8
  # are explicitly undefined, as opposed to nil which represents the absence of
9
9
  # a value. It is immutable and implements custom string representations for
10
- # debugging purposes.
10
+ # debugging purposes
11
11
  #
12
+ # @api private
13
+ # @!visibility private
12
14
  # @author {https://aaronmallen.me Aaron Allen}
13
15
  # @since 0.1.0
14
16
  Undefined = Object.new.tap do |undefined|
15
- # Returns self to prevent cloning.
17
+ # Prevent cloning of the singleton
16
18
  #
17
19
  # @return [Undefined] self
18
20
  def undefined.clone(...)
19
21
  self
20
22
  end
21
23
 
22
- # Returns self to prevent duplication.
24
+ # Prevent duplication of the singleton
23
25
  #
24
26
  # @return [Undefined] self
25
27
  def undefined.dup
26
28
  self
27
29
  end
28
30
 
29
- # Returns a string representation of the object.
31
+ # Get a string representation of the object
30
32
  #
31
33
  # @return [String] the string 'Undefined'
32
34
  def undefined.inspect
33
35
  to_s
34
36
  end
35
37
 
36
- # Converts the object to a string.
38
+ # Convert the object to a string
37
39
  #
38
40
  # @return [String] the string 'Undefined'
39
41
  def undefined.to_s
@@ -8,38 +8,64 @@ require 'domainic/attributer/instance_methods'
8
8
  require 'domainic/attributer/undefined'
9
9
 
10
10
  module Domainic
11
- # Core functionality for defining and managing Ruby class attributes.
11
+ # `Domainic::Attributer` is a powerful toolkit that brings clarity and safety to your Ruby class attributes.
12
+ # Ever wished your class attributes could:
12
13
  #
13
- # This module provides a flexible attribute system for Ruby classes that supports
14
- # positional arguments and keyword options with features like type validation,
15
- # coercion, and visibility control.
14
+ # * Validate themselves to ensure they only accept correct values?
15
+ # * Transform input data automatically into the right format?
16
+ # * Have clear, enforced visibility rules?
17
+ # * Handle their own default values intelligently?
18
+ # * Tell you when they change?
19
+ # * Distinguish between required arguments and optional settings?
16
20
  #
17
- # Can be included directly with default method names or customized via {Domainic.Attributer}.
21
+ # That's exactly what `Domainic::Attributer` does! It provides a declarative way to define and manage attributes
22
+ # in your Ruby classes, ensuring data integrity and clear interfaces. It's particularly valuable for:
18
23
  #
19
- # @example Basic usage with default method names
20
- # class Person
24
+ # * Domain models and value objects
25
+ # * Service objects and command patterns
26
+ # * Configuration objects
27
+ # * Any class where attribute behavior matters
28
+ #
29
+ # Think of it as giving your attributes a brain - they know what they want, how they should behave, and
30
+ # they're not afraid to speak up when something's not right!
31
+ #
32
+ # @see file:docs/USAGE.md Usage Guide
33
+ # @abstract Can be included directly with default method names or customized via {.Attributer}
34
+ #
35
+ # @example Basic usage
36
+ # class SuperDev
21
37
  # include Domainic::Attributer
22
38
  #
23
- # argument :name
24
- # option :age
39
+ # argument :code_name, String
40
+ #
41
+ # option :power_level, Integer, default: 9000
42
+ # option :favorite_gem do
43
+ # validate_with ->(val) { val.to_s.end_with?('ruby') }
44
+ # coerce_with ->(val) { val.to_s.downcase }
45
+ # non_nilable
46
+ # end
25
47
  # end
26
48
  #
27
- # @example Custom method names
28
- # class Person
29
- # include Domainic.Attributer(argument: :param, option: :opt)
49
+ # dev = SuperDev.new('RubyNinja', favorite_gem: 'RAILS_RUBY')
50
+ # # => #<SuperDev:0x00000001083aeb58 @code_name="RubyNinja", @favorite_gem="rails_ruby", @power_level=9000>
30
51
  #
31
- # param :name
32
- # opt :age
33
- # end
52
+ # dev.favorite_gem # => "rails_ruby"
53
+ # dev.power_level = 9001 # => 9001
54
+ # dev.power_level = 'over 9000'
55
+ # # `SuperDev#power_level`: has invalid value: "over 9000" (ArgumentError)
34
56
  #
35
57
  # @author {https://aaronmallen.me Aaron Allen}
36
58
  # @since 0.1.0
37
59
  module Attributer
38
60
  class << self
39
- # Create a customized Attributer module.
61
+ # Create a customized Attributer module
62
+ #
63
+ # @!visibility private
64
+ # @api private
40
65
  #
41
66
  # @param argument [Symbol, String] custom name for the argument method
42
67
  # @param option [Symbol, String] custom name for the option method
68
+ #
43
69
  # @return [Module] configured Attributer module
44
70
  # @rbs (?argument: (String | Symbol)?, ?option: (String | Symbol)?) -> Module
45
71
  def call(argument: :argument, option: :option)
@@ -55,9 +81,13 @@ module Domainic
55
81
  end
56
82
  end
57
83
 
58
- # Handle direct module inclusion.
84
+ # Handle direct module inclusion
85
+ #
86
+ # @!visibility private
87
+ # @api private
59
88
  #
60
89
  # @param base [Class, Module] the including class/module
90
+ #
61
91
  # @return [void]
62
92
  # @rbs (untyped base) -> void
63
93
  def included(base)
@@ -67,10 +97,11 @@ module Domainic
67
97
 
68
98
  private
69
99
 
70
- # Configure base class with Attributer functionality.
100
+ # Configure base class with Attributer functionality
71
101
  #
72
102
  # @param base [Class, Module] the target class/module
73
- # @param options [Hash] method name customization options
103
+ # @param options [Hash{Symbol => String, Symbol}] method name customization options
104
+ #
74
105
  # @return [void]
75
106
  # @rbs (untyped base, ?argument: (String | Symbol)?, ?option: (String | Symbol)?) -> void
76
107
  def include_attributer(base, **options)
@@ -79,10 +110,11 @@ module Domainic
79
110
  inject_custom_methods!(base, **options)
80
111
  end
81
112
 
82
- # Set up custom method names.
113
+ # Set up custom method names
83
114
  #
84
115
  # @param base [Class, Module] the target class/module
85
- # @param options [Hash] method name customization options
116
+ # @param options [Hash{Symbol => String, Symbol}] method name customization options
117
+ #
86
118
  # @return [void]
87
119
  # @rbs (untyped base, ?argument: (String | Symbol)?, ?option: (String | Symbol)?) -> void
88
120
  def inject_custom_methods!(base, **options)
@@ -96,17 +128,46 @@ module Domainic
96
128
  end
97
129
  end
98
130
 
99
- # Create a customized Attributer module.
100
- #
101
- # Provides a convenient way to include Attributer with customized method names.
131
+ # Provides a convenient way to include {Attributer} with customized method names
102
132
  #
103
- # @example
133
+ # @example Customizing method names
104
134
  # class Person
105
135
  # include Domainic.Attributer(argument: :param, option: :opt)
136
+ #
137
+ # param :name, String
138
+ # opt :age, Integer
106
139
  # end
107
140
  #
108
- # @param options [Hash] method name customization options
109
- # @return [Module] configured Attributer module
141
+ # Person.respond_to?(:argument) # => false
142
+ # Person.respond_to?(:param) # => true
143
+ # Person.respond_to?(:option) # => false
144
+ # Person.respond_to?(:opt) # => true
145
+ #
146
+ # person = Person.new('Alice', age: 30)
147
+ # # => #<Person:0x000000010865d188 @age=30, @name="Alice">
148
+ #
149
+ # @example Turning off a method
150
+ #
151
+ # class Person
152
+ # include Domainic.Attributer(argument: nil)
153
+ #
154
+ # option :name, String
155
+ # option :age, Integer
156
+ # end
157
+ #
158
+ # Person.respond_to?(:argument) # => false
159
+ # Person.respond_to?(:option) # => true
160
+ #
161
+ # person = Person.new(name: 'Alice', age: 30)
162
+ # # => #<Person:0x000000010865d188 @age=30, @name="Alice">
163
+ #
164
+ # @param options [Hash{Symbol => String, Symbol, nil}] method name customization options
165
+ # @option options [String, Symbol, nil] :argument custom name for the {Attributer::ClassMethods#argument argument}
166
+ # method. Set to `nil` to disable the method entirely
167
+ # @option options [String, Symbol, nil] :option custom name for the {Attributer::ClassMethods#option option}
168
+ # method. Set to `nil` to disable the method entirely
169
+ #
170
+ # @return [Module] the configured {Attributer} module
110
171
  # @rbs (?argument: (String | Symbol)?, ?option: (String | Symbol)?) -> Module
111
172
  def self.Attributer(**options) # rubocop:disable Naming/MethodName
112
173
  Domainic::Attributer.call(**options)