Module: Musa::Series::Serie Private

Defined in:
lib/musa-dsl/series/base-series.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Serie module factory providing configurable serie modules.

Creates modules dynamically based on requirements:

  • Serie.base: Minimal module without dependencies
  • Serie.with: Configured module with source/sources/block

Factory Pattern

Serie.with generates modules at runtime with specific features:

# Generate module with source support
include Serie.with(source: true, source_as: :upstream)

# Now has @source, #upstream, #upstream= methods

Configuration Options

  • source: Single upstream serie dependency
  • sources: Multiple upstream serie dependencies
  • block: Block/proc attribute
  • smart_block: SmartProcBinder-wrapped block

Musical Applications

Used internally by serie implementations to declare dependencies and automatically handle prototype/instance propagation.

See Also:

Defined Under Namespace

Modules: Prototyping

Class Method Summary collapse

Class Method Details

.baseModule

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates base serie module without dependencies.

Minimal module for series that generate values without upstream sources (e.g., array-backed series, value generators).

Examples:

Base serie

class SimpleSerie
  include Serie.base

  def _next_value
    # Generate value
  end
end

Returns:

  • (Module)

    base module with SerieImplementation



242
243
244
245
246
247
248
249
250
251
252
# File 'lib/musa-dsl/series/base-series.rb', line 242

def self.base
  Module.new do
    include SerieImplementation

    def has_source; false; end
    private def mandatory_source; false; end

    def has_sources; false; end
    private def mandatory_sources; false; end
  end
end

.with(source: false, source_as: nil, private_source: nil, mandatory_source: nil, sources: false, sources_as: nil, private_sources: nil, mandatory_sources: nil, smart_block: false, block: false, block_as: nil) ⇒ Module

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates configurable serie module with specified features.

Factory method generating modules with:

  • Single source dependency (source: true)
  • Multiple sources dependency (sources: true)
  • Block attribute (block: true, smart_block: true)

Source Support

source: true adds:

  • @source instance variable
  • #source getter (or custom name via source_as:)
  • #source= setter with state validation
  • Automatic prototype/instance propagation

Sources Support

sources: true adds:

  • @sources instance variable (Hash or Array)
  • #sources getter/setter
  • Automatic state resolution from all sources

Block Support

block: true - Simple proc attribute smart_block: true - SmartProcBinder-wrapped block

State Propagation

Sources automatically propagate state:

  • Setting source to :prototype → marks self as :prototype
  • Setting source to :instance → marks self as :instance
  • Cloning propagates through source/sources

Examples:

Serie with single source

class ReverseSerie
  include Serie.with(source: true)

  def _next_value
    # Process source.next_value
  end
end

Serie with block

class MapSerie
  include Serie.with(source: true, smart_block: true)

  def _next_value
    value = source.next_value
    value ? @block.call(value) : nil
  end
end

Parameters:

  • source (Boolean) (defaults to: false)

    add single source dependency

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

    custom name for source attribute

  • private_source (Boolean, nil) (defaults to: nil)

    make source methods private

  • mandatory_source (Boolean, nil) (defaults to: nil)

    require source to be set

  • sources (Boolean) (defaults to: false)

    add multiple sources dependency

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

    custom name for sources attribute

  • private_sources (Boolean, nil) (defaults to: nil)

    make sources methods private

  • mandatory_sources (Boolean, nil) (defaults to: nil)

    require sources to be set

  • smart_block (Boolean) (defaults to: false)

    add SmartProcBinder block support

  • block (Boolean) (defaults to: false)

    add simple block support

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

    custom name for block attribute

Returns:

  • (Module)

    configured module with SerieImplementation



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/musa-dsl/series/base-series.rb', line 326

def self.with(source: false,
              source_as: nil,
              private_source: nil,
              mandatory_source: nil,
              sources: false,
              sources_as: nil,
              private_sources: nil,
              mandatory_sources: nil,
              smart_block: false,
              block: false,
              block_as: nil)

  source_as ||= :source
  source_setter = (source_as.to_s + '=').to_sym
  _mandatory_source = source if mandatory_source.nil?

  sources_as ||= :sources
  sources_setter = (sources_as.to_s + '=').to_sym
  _mandatory_sources = sources if mandatory_sources.nil?

  block_as ||= :proc
  block_setter = (block_as.to_s + '=').to_sym

  Module.new do
    include SerieImplementation

    if source
      private def has_source; true; end
      define_method(:mandatory_source) { _mandatory_source }
      private :mandatory_source

      define_method source_as do
        @source
      end

      define_method source_setter do |serie|
        unless @source.nil? || @source.undefined? || serie.state == @source.state
          raise ArgumentError, "New serie for #{source_as} should be a #{@state} instead of a #{serie.state}"
        end

        @source = serie
        mark_regarding! @source
      end

      if private_source
        private source_as
        private source_setter
      end
    else
      private def has_source; false; end
      private def mandatory_source; false; end
    end

    if sources
      private def has_sources; true; end
      define_method(:mandatory_sources) { _mandatory_sources }
      private :mandatory_source

      define_method sources_as do
        @sources
      end

      define_method sources_setter do |series|
        unless series.is_a?(Hash) || series.is_a?(Array)
          raise ArgumentError, "New series for #{sources_as} should be a Hash or an Array instead of a #{series.class.name}"
        end

        @sources = series
        try_to_resolve_undefined_state_if_needed
      end

      if private_sources
        private sources_as
        private sources_setter
      end
    else
      private def has_sources; false; end
      private def mandatory_sources; false; end
    end

    if smart_block
      define_method block_as do |&block|
        if block
          @block = Extension::SmartProcBinder::SmartProcBinder.new(block)
        else
          @block.proc
        end
      end

      define_method block_setter do |block|
        @block = Extension::SmartProcBinder::SmartProcBinder.new(block)
      end

    elsif block
      define_method block_as do |&block|
        if block
          @block = block
        else
          @block
        end
      end

      define_method block_setter do |block|
        @block = block
      end
    end
  end
end