domainic-attributer 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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)