lib/democritus/class_builder/commands/attributes.rb in democritus-0.2.0 vs lib/democritus/class_builder/commands/attributes.rb in democritus-0.2.1
- old
+ new
@@ -10,42 +10,77 @@
# attribute(:name)
# attribute(:coolness_factor)
# end
class Attributes < ::Democritus::ClassBuilder::Command
# @param builder [Democritus::ClassBuilder]
- # @param additional_configuration [Proc] A means to nest additional configuration
- def initialize(builder:, &additional_configuration)
+ # @param pre_deferment_operation [Proc] A means to nest additional operations
+ def initialize(builder:, &pre_deferment_operation)
self.builder = builder
- self.additional_configuration = additional_configuration
+ self.pre_deferment_operation = pre_deferment_operation
self.attribute_names = []
end
- # :reek:NestedIterators: { exclude: [ 'Democritus::ClassBuilder::Commands::Attributes#call' ] }
- # :reek:TooManyStatements: { exclude: [ 'Democritus::ClassBuilder::Commands::Attributes#call' ] }
+ # @api public
+ #
+ # Method that generates the behavior for the Attributes command
+ #
+ # @return void
+ # @see Democritus::ClassBuilder#defer
def call
+ # In order to register any nested attributes, the pre_deferment_operation must be performed
+ # outside of the defer method call. If it were done inside the defer block, then the pre_deferment_operation
+ # might get lost.
+ execute_pre_deferment_operation
+ defer { |subject| configure(subject: subject) }
+ end
+
+ private
+
+ def execute_pre_deferment_operation
+ return unless pre_deferment_operation.respond_to?(:call)
# It may seem a little odd to yield self via an instance_exec, however in some cases I need a
# receiver for messages (i.e. FromJsonClassBuilder)
- instance_exec(self, &additional_configuration) if additional_configuration.respond_to?(:call)
- defer do |subject|
- subject.module_exec(@attribute_names) do |attribute_names|
- define_method(:initialize) do |**attributes|
- attribute_names.each do |attribute_name|
- send("#{attribute_name}=", attributes.fetch(attribute_name.to_sym, nil))
- end
+ instance_exec(self, &pre_deferment_operation)
+ end
+
+ # :reek:NestedIterators: { exclude: [ 'Democritus::ClassBuilder::Commands::Attributes#configure' ] }
+ def configure(subject:)
+ subject.module_exec(@attribute_names) do |attribute_names|
+ define_method(:initialize) do |**attributes|
+ attribute_names.each do |attribute_name|
+ send("#{attribute_name}=", attributes.fetch(attribute_name.to_sym, nil))
end
end
end
end
+ public
+
+ # @!group Commands Available Within the pre_deferment_operation
+
+ # @api public
+ #
+ # Exposes a mechanism for assigning individual attributes as part of the #attributes command.
+ #
+ # @param name [#to_sym] the name of the attribute
+ # @param options [Hash] additional options passed to the builder#attribute command
+ #
+ # @see Democritus::ClassBuilder::Commands::Attribute
+ # @see Democritus::ClassBuilder
def attribute(name:, **options)
name = name.to_sym
attribute_names << name
builder.attribute(name: name, **options)
end
+ # @!endgroup
+
private
- attr_accessor :additional_configuration, :attribute_names
+ attr_accessor :pre_deferment_operation
+
+ # [Array] of attribute names that have been generated
+ attr_accessor :attribute_names
end
end
end
end