Module: Musa::Series::Serie::Prototyping 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.

Prototype/instance state management for Series.

Implements the prototype/instance pattern enabling reusable serie definitions. Every serie exists in one of three states:

States

  • :prototype - Template state, cannot consume, can create instances
  • :instance - Active state, can consume values, has independent state
  • :undefined - Unresolved state, dependencies not yet resolved

State Queries

serie.state        # => :prototype | :instance | :undefined
serie.prototype?   # => true if prototype
serie.instance?    # => true if instance
serie.undefined?   # => true if undefined

State Transitions

Prototype Creation

Created by constructors (S, E, RND, etc.):

proto = S(1, 2, 3)
proto.prototype?  # => true

Instance Creation

Via .instance (or .i alias):

inst = proto.instance
inst.instance?  # => true

State Resolution

Undefined series resolve state from sources:

proxy = PROXY()  # Undefined
proxy.source = S(1, 2, 3)  # Becomes prototype

Cloning Behavior

Creating instance clones the serie and all dependencies:

proto = S(1, 2, 3).map { |x| x * 2 }
inst = proto.instance  # Clones both map and S

Validation

Operations check state permissions:

  • next_value, restart require :instance
  • infinite?, to_a allow :prototype
  • Undefined state raises PrototypingError

Musical Applications

  • Reusable melodic patterns
  • Multiple independent playbacks
  • Lazy definition of transformations
  • Memory-efficient pattern libraries

Defined Under Namespace

Classes: PrototypingError

Instance Method Summary collapse

Instance Method Details

#defined?Boolean

Checks if serie state is defined (not undefined).

Returns:

  • (Boolean)

    true if prototype or instance, false if undefined



557
558
559
# File 'lib/musa-dsl/series/base-series.rb', line 557

def defined?
  !undefined?
end

#instanceSerie Also known as: i

Creates or returns instance of serie.

  • If already instance, returns self
  • If prototype, creates new instance by cloning
  • If undefined, raises PrototypingError

Cloning Process

  1. Clones serie structure
  2. Marks clone as :instance
  3. Propagates instance creation to sources
  4. Calls init if defined

Each call creates independent instance with separate state.

Examples:

Create instances

proto = S(1, 2, 3)
a = proto.instance
b = proto.instance  # Different instance

a.next_value  # => 1
b.next_value  # => 1 (independent)

Returns:

  • (Serie)

    instance serie

Raises:



627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
# File 'lib/musa-dsl/series/base-series.rb', line 627

def instance
  try_to_resolve_undefined_state_if_needed

  if instance?
    self
  elsif prototype?
    new_instance = clone

    new_instance._instance!
    new_instance.mark_as_instance!(self)
    new_instance.init if new_instance.respond_to?(:init)

    new_instance
  else
    raise PrototypingError, 'Can\'t get an instance of an undefined serie'
  end
end

#instance?Boolean

Checks if serie is in instance state.

Returns:

  • (Boolean)

    true if instance, false otherwise



537
538
539
540
# File 'lib/musa-dsl/series/base-series.rb', line 537

def instance?
  try_to_resolve_undefined_state_if_needed
  @state&.==(:instance)
end

#prototypeSerie Also known as: p

Returns prototype of serie.

  • If already prototype, returns self
  • If instance, returns original prototype (if available)
  • If undefined, raises PrototypingError

Examples:

Get prototype

proto = S(1, 2, 3)
inst = proto.instance
inst.prototype  # => proto

Returns:

  • (Serie)

    prototype serie

Raises:



577
578
579
580
581
582
583
584
585
586
587
588
589
590
# File 'lib/musa-dsl/series/base-series.rb', line 577

def prototype
  try_to_resolve_undefined_state_if_needed

  if prototype?
    self
  elsif instance?
    # if the series has been directly created as an instance (i.e., because is an operation over an instance)
    # the prototype doesn't exist.
    #
    @instance_of
  else
    raise PrototypingError, 'Can\'t get the prototype of an undefined serie'
  end
end

#prototype?Boolean

Checks if serie is in prototype state.

Returns:

  • (Boolean)

    true if prototype, false otherwise



527
528
529
530
# File 'lib/musa-dsl/series/base-series.rb', line 527

def prototype?
  try_to_resolve_undefined_state_if_needed
  @state&.==(:prototype)
end

#stateSymbol

Returns current state of serie.

Attempts to resolve undefined state from sources before returning. State is one of: :prototype, :instance, or :undefined.

Returns:

  • (Symbol)

    current state (:prototype, :instance, :undefined)



517
518
519
520
# File 'lib/musa-dsl/series/base-series.rb', line 517

def state
  try_to_resolve_undefined_state_if_needed
  @state || :undefined
end

#undefined?Boolean

Checks if serie is in undefined state.

Returns:

  • (Boolean)

    true if undefined, false otherwise



547
548
549
550
# File 'lib/musa-dsl/series/base-series.rb', line 547

def undefined?
  try_to_resolve_undefined_state_if_needed
  @state.nil? || @state == :undefined
end