Module: Musa::Extension::AttributeBuilder

Overview

Module providing metaprogramming methods for creating DSL builder patterns.

AttributeBuilder defines class methods that generate instance methods for creating and managing collections of objects in a DSL-friendly way. It's heavily used throughout Musa DSL to create fluent, expressive APIs.

Method Categories

  • Adders to Hash: Create methods that build hash-based collections
  • Adders to Array: Create methods that build array-based collections
  • Builders: Create single-object getter/setter DSL methods

Naming Conventions

  • add_item / item: singular form adds one object
  • items: plural form adds multiple or retrieves collection
  • Automatic pluralization (item → items) unless specified

Examples:

Using in a class

class Score
  extend Musa::Extension::AttributeBuilder

  def initialize
    @tracks = {}
  end

  attr_tuple_adder_to_hash :track, Track
end

score = Score.new
score.add_track :piano, params
score.tracks  # => { piano: Track(...) }

See Also:

Instance Method Summary collapse

Instance Method Details

#attr_complex_adder_to_array(name, klass, plural: nil, variable: nil) ⇒ Object

Creates methods for adding complex objects (with multiple parameters) to an array.

Supports both positional and keyword arguments when creating instances.

Parameters:

  • name (Symbol)

    singular name.

  • klass (Class)

    class to instantiate.

  • plural (Symbol, nil) (defaults to: nil)

    plural name.

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 109

def attr_complex_adder_to_array(name, klass, plural: nil, variable: nil)

  plural ||= name.to_s + 's'
  variable ||= ('@' + plural.to_s).to_sym

  adder_method = "add_#{name}".to_sym

  define_method adder_method do |*parameters, **key_parameters, &block|
    klass.new(*parameters, **key_parameters, &block).tap do |object|
      instance_variable_get(variable) << object
    end
  end

  if plural == name
    define_method plural do |*parameters, **key_parameters, &block|
      if parameters.empty? && key_parameters.empty? && block.nil?
        instance_variable_get variable
      else
        send adder_method, *parameters, **key_parameters, &block
      end
    end
  else
    alias_method name, adder_method

    define_method plural do
      instance_variable_get variable
    end
  end
end

#attr_complex_adder_to_custom(name, plural: nil, variable: nil) { ... } ⇒ Object

Creates methods for adding complex objects with custom construction logic.

The block receives parameters and should construct and add the object.

Parameters:

  • name (Symbol)

    singular name.

  • plural (Symbol, nil) (defaults to: nil)

    plural name.

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name.

Yields:

  • Constructor block executed in instance context.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 148

def attr_complex_adder_to_custom(name, plural: nil, variable: nil, &constructor_and_adder)

  plural ||= name.to_s + 's'

  adder_method = "add_#{name}".to_sym

  define_method adder_method do |*parameters, **key_parameters, &block|
    instance_exec(*parameters, **key_parameters, &constructor_and_adder).tap do |object|
      object.with &block if block
    end
  end

  if plural == name && variable
    define_method plural do |*parameters, **key_parameters, &block|
      if parameters.empty? && key_parameters.empty? && block.nil?
        instance_variable_get variable
      else
        send adder_method, *parameters, **key_parameters, &block
      end
    end
  else
    alias_method name, adder_method

    if variable
      define_method plural do
        instance_variable_get variable
      end
    end
  end
end

#attr_complex_builder(name, klass, variable: nil, first_parameter: nil) ⇒ Object

Creates a getter/setter DSL method for complex objects with multiple parameters.

Supports optional first_parameter that's automatically prepended when constructing.

Parameters:

  • name (Symbol)

    attribute name.

  • klass (Class)

    class to instantiate.

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name.

  • first_parameter (Object, nil) (defaults to: nil)

    parameter automatically prepended to constructor.



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 232

def attr_complex_builder(name, klass, variable: nil, first_parameter: nil)
  variable ||= ('@' + name.to_s).to_sym

  define_method name do |*parameters, **key_parameters, &block|
    if parameters.empty? && key_parameters.empty? && block.nil?
      instance_variable_get variable
    else
      if first_parameter
        klass.new(first_parameter, *parameters, **key_parameters, &block).tap do |object|
          instance_variable_set variable, object
        end
      else
        klass.new(*parameters, **key_parameters, &block).tap do |object|
          instance_variable_set variable, object
        end
      end
    end
  end

  attr_writer name
end

#attr_simple_builder(name, klass = nil, variable: nil) ⇒ Object

Creates a simple getter/setter DSL method for a single value.

Parameters:

  • name (Symbol)

    attribute name.

  • klass (Class, nil) (defaults to: nil)

    class to instantiate (nil = use value as-is).

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name.



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 184

def attr_simple_builder(name, klass = nil, variable: nil)
  variable ||= ('@' + name.to_s).to_sym

  define_method name do |parameter = nil, &block|
    if parameter.nil?
      instance_variable_get variable
    else
      (klass&.new(parameter, &block) || parameter).tap do |object|
        instance_variable_set variable, object
      end
    end
  end

  attr_writer name
end

#attr_tuple_adder_to_array(name, klass, plural: nil, variable: nil) ⇒ Object

Creates methods for adding id/value tuples to an array collection.

Similar to attr_tuple_adder_to_hash but stores items in an array instead of hash. Useful when order matters or duplicates are allowed.

Parameters:

  • name (Symbol)

    singular name for the item.

  • klass (Class)

    class to instantiate.

  • plural (Symbol, nil) (defaults to: nil)

    plural name.

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 80

def attr_tuple_adder_to_array(name, klass, plural: nil, variable: nil)

  plural ||= name.to_s + 's'
  variable ||= ('@' + plural.to_s).to_sym

  adder_method = "add_#{name}".to_sym

  define_method adder_method do |id, parameter, &block|
    klass.new(id, parameter, &block).tap do |object|
      instance_variable_get(variable) << object
    end
  end

  define_method plural do |**parameters, &block|
    parameters.each_pair do |id, value|
      send adder_method, id, value, &block
    end
    instance_variable_get variable
  end
end

#attr_tuple_adder_to_hash(name, klass, plural: nil, variable: nil) ⇒ Object

Creates methods for adding id/value tuples to a hash collection.

Generates:

  • add_#{name}(id, parameter) → creates instance and adds to hash
  • #{plural}(**parameters) → batch add or retrieve hash

Parameters:

  • name (Symbol)

    singular name for the item.

  • klass (Class)

    class to instantiate (receives id, parameter).

  • plural (Symbol, nil) (defaults to: nil)

    plural name (defaults to name + 's').

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name (defaults to '@' + plural).



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 50

def attr_tuple_adder_to_hash(name, klass, plural: nil, variable: nil)

  plural ||= name.to_s + 's'
  variable ||= ('@' + plural.to_s).to_sym

  adder_method = "add_#{name}".to_sym

  define_method adder_method do |id, parameter|
    klass.new(id, parameter).tap do |object|
      instance_variable_get(variable)[id] = object
    end
  end

  define_method plural do |**parameters|
    parameters&.each_pair do |id, value|
      send adder_method, id, value
    end
    instance_variable_get variable
  end
end

#attr_tuple_builder(name, klass, variable: nil) ⇒ Object

Creates a getter/setter DSL method for a single id/value tuple.

Parameters:

  • name (Symbol)

    attribute name.

  • klass (Class)

    class to instantiate.

  • variable (Symbol, nil) (defaults to: nil)

    instance variable name.



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/musa-dsl/core-ext/attribute-builder.rb', line 205

def attr_tuple_builder(name, klass, variable: nil)
  variable ||= ('@' + name.to_s).to_sym

  define_method name do |**parameters, &block|
    if parameters.empty?
      instance_variable_get variable
    elsif parameters.size == 1
      parameter = parameters.first
      klass.new(*parameter, &block).tap do |object|
        instance_variable_set variable, object
      end
    else
      raise ArgumentError, "Method #{name} can only create instances with one id: value arguments pattern"
    end
  end

  attr_writer name
end