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



361
362
363
# File 'lib/musa-dsl/series/base-series.rb', line 361

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:



431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/musa-dsl/series/base-series.rb', line 431

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



341
342
343
344
# File 'lib/musa-dsl/series/base-series.rb', line 341

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:



381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/musa-dsl/series/base-series.rb', line 381

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



331
332
333
334
# File 'lib/musa-dsl/series/base-series.rb', line 331

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)



321
322
323
324
# File 'lib/musa-dsl/series/base-series.rb', line 321

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



351
352
353
354
# File 'lib/musa-dsl/series/base-series.rb', line 351

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