musa-dsl 0.23.0 → 0.23.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/musa-dsl/midi/midi-voices.rb +7 -7
 - data/lib/musa-dsl/series/base-series.rb +3 -3
 - data/lib/musa-dsl/series/buffer-serie.rb +7 -8
 - data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +33 -18
 - data/lib/musa-dsl/series/main-serie-constructors.rb +1 -1
 - data/lib/musa-dsl/series/main-serie-operations.rb +43 -0
 - data/lib/musa-dsl/series/proxy-serie.rb +9 -5
 - data/lib/musa-dsl/series/series-composer.rb +227 -54
 - data/musa-dsl.gemspec +2 -2
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 19683437b5ef89739c0d1283c86b18c547a24dd058ca5013abdea4f9c6335f5c
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 99fea2b0076baf8976050bd9467f4ecafb87a44bad1b37933e741116f1f5ec96
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 26765814873920f392a76fdef1f8f7fc6ce3baca086d47ba443fb74246768943dbe074ebc35b71d946aab7136fd6a433fe03ad897bcff8a16e7045a1fd0c5e7f
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 57a1761af4bb50cb40c75680e89716e8f21b8f5a4ea345b42bdb3e2065f58a315fac8b579227741b601c25f2e2e8a617d7fef2cd799366f7df4b749c9a532ec9
         
     | 
| 
         @@ -10,7 +10,7 @@ using Musa::Extension::ExplodeRanges 
     | 
|
| 
       10 
10 
     | 
    
         
             
            module Musa
         
     | 
| 
       11 
11 
     | 
    
         
             
              module MIDIVoices
         
     | 
| 
       12 
12 
     | 
    
         
             
                class MIDIVoices
         
     | 
| 
       13 
     | 
    
         
            -
                  attr_accessor : 
     | 
| 
      
 13 
     | 
    
         
            +
                  attr_accessor :do_log
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                  def initialize(sequencer:, output:, channels:, do_log: nil)
         
     | 
| 
       16 
16 
     | 
    
         
             
                    do_log ||= false
         
     | 
| 
         @@ -24,7 +24,7 @@ module Musa 
     | 
|
| 
       24 
24 
     | 
    
         
             
                  end
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                  def reset
         
     | 
| 
       27 
     | 
    
         
            -
                    @voices = @channels.collect { |channel| MIDIVoice.new 
     | 
| 
      
 27 
     | 
    
         
            +
                    @voices = @channels.collect { |channel| MIDIVoice.new(sequencer: @sequencer, output: @output, channel: channel, do_log: @do_log) }.freeze
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
                  attr_reader :voices
         
     | 
| 
         @@ -48,14 +48,14 @@ module Musa 
     | 
|
| 
       48 
48 
     | 
    
         
             
                  attr_accessor :name, :do_log
         
     | 
| 
       49 
49 
     | 
    
         
             
                  attr_reader :sequencer, :output, :channel, :active_pitches, :tick_duration
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                  def initialize(sequencer:, output:, channel:, name: nil,  
     | 
| 
       52 
     | 
    
         
            -
                     
     | 
| 
      
 51 
     | 
    
         
            +
                  def initialize(sequencer:, output:, channel:, name: nil, do_log: nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    do_log ||= false
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
                    @sequencer = sequencer
         
     | 
| 
       55 
55 
     | 
    
         
             
                    @output = output
         
     | 
| 
       56 
56 
     | 
    
         
             
                    @channel = channel
         
     | 
| 
       57 
57 
     | 
    
         
             
                    @name = name
         
     | 
| 
       58 
     | 
    
         
            -
                    @do_log =  
     | 
| 
      
 58 
     | 
    
         
            +
                    @do_log = do_log
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
                    @tick_duration = Rational(1, @sequencer.ticks_per_bar)
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
         @@ -64,7 +64,7 @@ module Musa 
     | 
|
| 
       64 
64 
     | 
    
         
             
                    @active_pitches = []
         
     | 
| 
       65 
65 
     | 
    
         
             
                    fill_active_pitches @active_pitches
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                     
     | 
| 
      
 67 
     | 
    
         
            +
                    @sequencer.logger.warn 'voice without output' unless @output
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                    self
         
     | 
| 
       70 
70 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -118,7 +118,7 @@ module Musa 
     | 
|
| 
       118 
118 
     | 
    
         
             
                  end
         
     | 
| 
       119 
119 
     | 
    
         | 
| 
       120 
120 
     | 
    
         
             
                  def log(msg)
         
     | 
| 
       121 
     | 
    
         
            -
                    @sequencer. 
     | 
| 
      
 121 
     | 
    
         
            +
                    @sequencer.logger.info('MIDIVoice') { "voice #{name || @channel}: #{msg}" } if @do_log
         
     | 
| 
       122 
122 
     | 
    
         
             
                  end
         
     | 
| 
       123 
123 
     | 
    
         | 
| 
       124 
124 
     | 
    
         
             
                  def to_s
         
     | 
| 
         @@ -38,12 +38,12 @@ module Musa 
     | 
|
| 
       38 
38 
     | 
    
         
             
                      include SerieImplementation
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                      if source
         
     | 
| 
       41 
     | 
    
         
            -
                        define_method source_as do 
     | 
| 
      
 41 
     | 
    
         
            +
                        define_method source_as do
         
     | 
| 
       42 
42 
     | 
    
         
             
                          @source
         
     | 
| 
       43 
43 
     | 
    
         
             
                        end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                        define_method source_setter do |serie|
         
     | 
| 
       46 
     | 
    
         
            -
                          raise ArgumentError, "New  
     | 
| 
      
 46 
     | 
    
         
            +
                          raise ArgumentError, "New #{source_as} should be a #{@get}" unless @source.nil? || @source.prototype? == serie&.prototype?
         
     | 
| 
       47 
47 
     | 
    
         | 
| 
       48 
48 
     | 
    
         
             
                          serie ||= Musa::Series::Constructors.NIL
         
     | 
| 
       49 
49 
     | 
    
         
             
                          @get = serie&.instance? ? :instance : :prototype
         
     | 
| 
         @@ -294,7 +294,7 @@ module Musa 
     | 
|
| 
       294 
294 
     | 
    
         
             
                      @source&.infinite? || false
         
     | 
| 
       295 
295 
     | 
    
         
             
                    end
         
     | 
| 
       296 
296 
     | 
    
         | 
| 
       297 
     | 
    
         
            -
                    def to_a( 
     | 
| 
      
 297 
     | 
    
         
            +
                    def to_a(duplicate: nil, recursive: nil, restart: nil, dr: nil)
         
     | 
| 
       298 
298 
     | 
    
         
             
                      recursive ||= false
         
     | 
| 
       299 
299 
     | 
    
         | 
| 
       300 
300 
     | 
    
         
             
                      dr = instance? if dr.nil?
         
     | 
| 
         @@ -117,18 +117,18 @@ module Musa 
     | 
|
| 
       117 
117 
     | 
    
         
             
                    @buffer
         
     | 
| 
       118 
118 
     | 
    
         
             
                  end
         
     | 
| 
       119 
119 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                  private def _restart( 
     | 
| 
       121 
     | 
    
         
            -
                    raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless  
     | 
| 
      
 120 
     | 
    
         
            +
                  private def _restart(buffer)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless buffer
         
     | 
| 
       122 
122 
     | 
    
         
             
                    return if @source_just_restarted
         
     | 
| 
       123 
123 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                    next_nil = @nils.find { |_| _ >  
     | 
| 
      
 124 
     | 
    
         
            +
                    next_nil = @nils.find { |_| _ > buffer.index }
         
     | 
| 
       125 
125 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
                    if next_nil &&  
     | 
| 
       127 
     | 
    
         
            -
                       
     | 
| 
      
 126 
     | 
    
         
            +
                    if next_nil && buffer.index < next_nil
         
     | 
| 
      
 127 
     | 
    
         
            +
                      buffer.last_nil_index = buffer.index = next_nil
         
     | 
| 
       128 
128 
     | 
    
         | 
| 
       129 
129 
     | 
    
         
             
                    else
         
     | 
| 
       130 
130 
     | 
    
         
             
                      until _next_value.nil?; end
         
     | 
| 
       131 
     | 
    
         
            -
                       
     | 
| 
      
 131 
     | 
    
         
            +
                      buffer.last_nil_index = buffer.index = @nils.last
         
     | 
| 
       132 
132 
     | 
    
         
             
                    end
         
     | 
| 
       133 
133 
     | 
    
         | 
| 
       134 
134 
     | 
    
         
             
                    clear_old_history
         
     | 
| 
         @@ -216,8 +216,7 @@ module Musa 
     | 
|
| 
       216 
216 
     | 
    
         
             
                          @index += 1
         
     | 
| 
       217 
217 
     | 
    
         
             
                          value = @history[@index]
         
     | 
| 
       218 
218 
     | 
    
         
             
                        else
         
     | 
| 
       219 
     | 
    
         
            -
                          @source.next_value
         
     | 
| 
       220 
     | 
    
         
            -
                          value = _next_value
         
     | 
| 
      
 219 
     | 
    
         
            +
                          value = _next_value unless @source.next_value.nil?
         
     | 
| 
       221 
220 
     | 
    
         
             
                        end
         
     | 
| 
       222 
221 
     | 
    
         | 
| 
       223 
222 
     | 
    
         
             
                        if value.nil?
         
     | 
| 
         @@ -1,19 +1,32 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Musa
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Series::Operations
         
     | 
| 
       3 
3 
     | 
    
         
             
                def split
         
     | 
| 
       4 
     | 
    
         
            -
                  Splitter.new( 
     | 
| 
      
 4 
     | 
    
         
            +
                  Splitter.new(self)
         
     | 
| 
       5 
5 
     | 
    
         
             
                end
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                class Splitter
         
     | 
| 
       8 
8 
     | 
    
         
             
                  include Enumerable
         
     | 
| 
      
 9 
     | 
    
         
            +
                  include Series::Serie::Prototyping
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                  def initialize( 
     | 
| 
       11 
     | 
    
         
            -
                    @ 
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(source)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @source = source
         
     | 
| 
       12 
13 
     | 
    
         
             
                    @series = {}
         
     | 
| 
       13 
14 
     | 
    
         
             
                  end
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
                  def source=(serie)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @source = serie
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @proxy.source = @source if @proxy
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  protected def _instance!
         
     | 
| 
      
 22 
     | 
    
         
            +
                    super
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @proxy = SplitterProxy.new(@source)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       15 
26 
     | 
    
         
             
                  def [](key_or_index)
         
     | 
| 
       16 
     | 
    
         
            -
                     
     | 
| 
      
 27 
     | 
    
         
            +
                    raise "Can't get a component because Splitter is a prototype. To get a component you need a Splitter instance." unless @is_instance
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    if @series.key?(key_or_index)
         
     | 
| 
       17 
30 
     | 
    
         
             
                      @series[key_or_index]
         
     | 
| 
       18 
31 
     | 
    
         
             
                    else
         
     | 
| 
       19 
32 
     | 
    
         
             
                      @series[key_or_index] = Split.new(@proxy, key_or_index)
         
     | 
| 
         @@ -21,6 +34,8 @@ module Musa 
     | 
|
| 
       21 
34 
     | 
    
         
             
                  end
         
     | 
| 
       22 
35 
     | 
    
         | 
| 
       23 
36 
     | 
    
         
             
                  def each
         
     | 
| 
      
 37 
     | 
    
         
            +
                    raise "Can't iterate because Splitter is a prototype. To iterate you need a Splitter instance." unless @is_instance
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
       24 
39 
     | 
    
         
             
                    if block_given?
         
     | 
| 
       25 
40 
     | 
    
         
             
                      if @proxy.hash_mode?
         
     | 
| 
       26 
41 
     | 
    
         
             
                        @proxy.components.each do |key|
         
     | 
| 
         @@ -60,24 +75,24 @@ module Musa 
     | 
|
| 
       60 
75 
     | 
    
         
             
                    end
         
     | 
| 
       61 
76 
     | 
    
         
             
                  end
         
     | 
| 
       62 
77 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                  class  
     | 
| 
       64 
     | 
    
         
            -
                    include Series::Serie::Prototyping
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
                  class SplitterProxy
         
     | 
| 
       66 
79 
     | 
    
         
             
                    def initialize(hash_or_array_serie)
         
     | 
| 
       67 
80 
     | 
    
         
             
                      @source = hash_or_array_serie
         
     | 
| 
       68 
     | 
    
         
            -
                       
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                      init
         
     | 
| 
      
 81 
     | 
    
         
            +
                      infer_components
         
     | 
| 
       71 
82 
     | 
    
         
             
                    end
         
     | 
| 
       72 
83 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
                    attr_reader : 
     | 
| 
      
 84 
     | 
    
         
            +
                    attr_reader :source
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    def source=(hash_or_array_serie)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      @source = hash_or_array_serie
         
     | 
| 
      
 88 
     | 
    
         
            +
                      infer_components
         
     | 
| 
      
 89 
     | 
    
         
            +
                    end
         
     | 
| 
       74 
90 
     | 
    
         | 
| 
       75 
91 
     | 
    
         
             
                    def hash_mode?; @hash_mode; end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
       76 
93 
     | 
    
         
             
                    def array_mode?; @array_mode; end
         
     | 
| 
       77 
94 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
                     
     | 
| 
       79 
     | 
    
         
            -
                      infer_components
         
     | 
| 
       80 
     | 
    
         
            -
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    attr_reader :components
         
     | 
| 
       81 
96 
     | 
    
         | 
| 
       82 
97 
     | 
    
         
             
                    def restart(key_or_index = nil)
         
     | 
| 
       83 
98 
     | 
    
         
             
                      if key_or_index
         
     | 
| 
         @@ -151,18 +166,18 @@ module Musa 
     | 
|
| 
       151 
166 
     | 
    
         
             
                    include Series::Serie.base
         
     | 
| 
       152 
167 
     | 
    
         | 
| 
       153 
168 
     | 
    
         
             
                    def initialize(proxy, key_or_index)
         
     | 
| 
       154 
     | 
    
         
            -
                      @ 
     | 
| 
      
 169 
     | 
    
         
            +
                      @proxy = proxy
         
     | 
| 
       155 
170 
     | 
    
         
             
                      @key_or_index = key_or_index
         
     | 
| 
       156 
171 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
                       
     | 
| 
      
 172 
     | 
    
         
            +
                      mark_as_instance!
         
     | 
| 
       158 
173 
     | 
    
         
             
                    end
         
     | 
| 
       159 
174 
     | 
    
         | 
| 
       160 
175 
     | 
    
         
             
                    private def _restart
         
     | 
| 
       161 
     | 
    
         
            -
                      @ 
     | 
| 
      
 176 
     | 
    
         
            +
                      @proxy.restart(@key_or_index)
         
     | 
| 
       162 
177 
     | 
    
         
             
                    end
         
     | 
| 
       163 
178 
     | 
    
         | 
| 
       164 
179 
     | 
    
         
             
                    private def _next_value
         
     | 
| 
       165 
     | 
    
         
            -
                      @ 
     | 
| 
      
 180 
     | 
    
         
            +
                      @proxy.next_value(@key_or_index)
         
     | 
| 
       166 
181 
     | 
    
         
             
                    end
         
     | 
| 
       167 
182 
     | 
    
         
             
                  end
         
     | 
| 
       168 
183 
     | 
    
         | 
| 
         @@ -116,6 +116,10 @@ module Musa 
     | 
|
| 
       116 
116 
     | 
    
         
             
                    Anticipate.new self, &block
         
     | 
| 
       117 
117 
     | 
    
         
             
                  end
         
     | 
| 
       118 
118 
     | 
    
         | 
| 
      
 119 
     | 
    
         
            +
                  def lazy(&block)
         
     | 
| 
      
 120 
     | 
    
         
            +
                    LazySerieEval.new self, &block
         
     | 
| 
      
 121 
     | 
    
         
            +
                  end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
       119 
123 
     | 
    
         
             
                  ###
         
     | 
| 
       120 
124 
     | 
    
         
             
                  ### Implementation
         
     | 
| 
       121 
125 
     | 
    
         
             
                  ###
         
     | 
| 
         @@ -1006,6 +1010,45 @@ module Musa 
     | 
|
| 
       1006 
1010 
     | 
    
         
             
                  end
         
     | 
| 
       1007 
1011 
     | 
    
         | 
| 
       1008 
1012 
     | 
    
         
             
                  private_constant :HashFromSeriesArray
         
     | 
| 
      
 1013 
     | 
    
         
            +
             
     | 
| 
      
 1014 
     | 
    
         
            +
                  class LazySerieEval
         
     | 
| 
      
 1015 
     | 
    
         
            +
                    include Serie.with(source: true, block: true)
         
     | 
| 
      
 1016 
     | 
    
         
            +
             
     | 
| 
      
 1017 
     | 
    
         
            +
                    def initialize(serie, &block)
         
     | 
| 
      
 1018 
     | 
    
         
            +
                      self.source = serie
         
     | 
| 
      
 1019 
     | 
    
         
            +
                      self.proc = block
         
     | 
| 
      
 1020 
     | 
    
         
            +
             
     | 
| 
      
 1021 
     | 
    
         
            +
                      init
         
     | 
| 
      
 1022 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1023 
     | 
    
         
            +
             
     | 
| 
      
 1024 
     | 
    
         
            +
                    def source=(serie)
         
     | 
| 
      
 1025 
     | 
    
         
            +
                      super
         
     | 
| 
      
 1026 
     | 
    
         
            +
                      @processed = nil
         
     | 
| 
      
 1027 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1028 
     | 
    
         
            +
             
     | 
| 
      
 1029 
     | 
    
         
            +
                    def proc(&block)
         
     | 
| 
      
 1030 
     | 
    
         
            +
                      super
         
     | 
| 
      
 1031 
     | 
    
         
            +
                      @processed = nil if block
         
     | 
| 
      
 1032 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1033 
     | 
    
         
            +
             
     | 
| 
      
 1034 
     | 
    
         
            +
                    def proc=(block)
         
     | 
| 
      
 1035 
     | 
    
         
            +
                      super
         
     | 
| 
      
 1036 
     | 
    
         
            +
                      @processed = nil if block
         
     | 
| 
      
 1037 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1038 
     | 
    
         
            +
             
     | 
| 
      
 1039 
     | 
    
         
            +
                    private def _restart
         
     | 
| 
      
 1040 
     | 
    
         
            +
                      @processed = nil
         
     | 
| 
      
 1041 
     | 
    
         
            +
                      @source.restart
         
     | 
| 
      
 1042 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1043 
     | 
    
         
            +
             
     | 
| 
      
 1044 
     | 
    
         
            +
                    private def _next_value
         
     | 
| 
      
 1045 
     | 
    
         
            +
                      @processed ||= @block.call(@source)
         
     | 
| 
      
 1046 
     | 
    
         
            +
                      @processed.next_value
         
     | 
| 
      
 1047 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1048 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1049 
     | 
    
         
            +
             
     | 
| 
      
 1050 
     | 
    
         
            +
                  private_constant :LazySerieEval
         
     | 
| 
       1009 
1051 
     | 
    
         
             
                end
         
     | 
| 
      
 1052 
     | 
    
         
            +
             
     | 
| 
       1010 
1053 
     | 
    
         
             
              end
         
     | 
| 
       1011 
1054 
     | 
    
         
             
            end
         
     | 
| 
         @@ -7,10 +7,10 @@ module Musa 
     | 
|
| 
       7 
7 
     | 
    
         
             
                end
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                class ProxySerie
         
     | 
| 
       10 
     | 
    
         
            -
                  include Series::Serie.with(source: true)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  include Series::Serie.with(source: true, source_as: :proxy_source)
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                  def initialize(serie)
         
     | 
| 
       13 
     | 
    
         
            -
                    self. 
     | 
| 
      
 13 
     | 
    
         
            +
                    self.proxy_source = serie
         
     | 
| 
       14 
14 
     | 
    
         
             
                    init
         
     | 
| 
       15 
15 
     | 
    
         
             
                  end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
         @@ -27,15 +27,19 @@ module Musa 
     | 
|
| 
       27 
27 
     | 
    
         
             
                  end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                  private def method_missing(method_name, *args, **key_args, &block)
         
     | 
| 
       30 
     | 
    
         
            -
                    if @source 
     | 
| 
       31 
     | 
    
         
            -
                      @source. 
     | 
| 
      
 30 
     | 
    
         
            +
                    if @source
         
     | 
| 
      
 31 
     | 
    
         
            +
                      if @source.respond_to?(method_name)
         
     | 
| 
      
 32 
     | 
    
         
            +
                        @source.send method_name, *args, **key_args, &block
         
     | 
| 
      
 33 
     | 
    
         
            +
                      else
         
     | 
| 
      
 34 
     | 
    
         
            +
                        raise NoMethodError, "undefined method '#{method_name}' for proxied #{@source.to_s}"
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
       32 
36 
     | 
    
         
             
                    else
         
     | 
| 
       33 
37 
     | 
    
         
             
                      super
         
     | 
| 
       34 
38 
     | 
    
         
             
                    end
         
     | 
| 
       35 
39 
     | 
    
         
             
                  end
         
     | 
| 
       36 
40 
     | 
    
         | 
| 
       37 
41 
     | 
    
         
             
                  private def respond_to_missing?(method_name, include_private)
         
     | 
| 
       38 
     | 
    
         
            -
                    @source && @source.respond_to?(method_name, include_private) # || super
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @source && @source.respond_to?(method_name, include_private) # || super ??
         
     | 
| 
       39 
43 
     | 
    
         
             
                  end
         
     | 
| 
       40 
44 
     | 
    
         
             
                end
         
     | 
| 
       41 
45 
     | 
    
         
             
              end
         
     | 
| 
         @@ -4,38 +4,58 @@ require_relative '../core-ext/with' 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module Musa
         
     | 
| 
       6 
6 
     | 
    
         
             
              module Series
         
     | 
| 
      
 7 
     | 
    
         
            +
                module Operations
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def composer(&block)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    Composer::Composer.new(&block).tap { |_| _.input.proxy_source = self}.output
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       7 
13 
     | 
    
         
             
                module Composer
         
     | 
| 
       8 
14 
     | 
    
         
             
                  class Composer
         
     | 
| 
       9 
15 
     | 
    
         
             
                    using Musa::Extension::Arrayfy
         
     | 
| 
       10 
16 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
      
 17 
     | 
    
         
            +
                    def initialize(inputs: [:input], outputs: [:output], auto_commit: nil, &block)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      auto_commit = true if auto_commit.nil?
         
     | 
| 
       12 
19 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                    def initialize(inputs: [:input], outputs: [:output], &block)
         
     | 
| 
       14 
20 
     | 
    
         
             
                      @pipelines = {}
         
     | 
| 
       15 
21 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                      @ 
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
                      def @pipelines.[]=(name, pipeline)
         
     | 
| 
      
 23 
     | 
    
         
            +
                        pipeline_to_add = @commited ? pipeline.commit! : pipeline
         
     | 
| 
      
 24 
     | 
    
         
            +
                        super(name, pipeline_to_add)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
       19 
26 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                      @dsl = DSLContext.new(@pipelines 
     | 
| 
      
 27 
     | 
    
         
            +
                      @dsl = DSLContext.new(@pipelines)
         
     | 
| 
       21 
28 
     | 
    
         
             
                      @inputs = {}
         
     | 
| 
       22 
29 
     | 
    
         
             
                      @outputs = {}
         
     | 
| 
       23 
30 
     | 
    
         | 
| 
       24 
31 
     | 
    
         
             
                      inputs&.each do |input|
         
     | 
| 
       25 
     | 
    
         
            -
                         
     | 
| 
       26 
     | 
    
         
            -
                        @pipelines[input] =  
     | 
| 
      
 32 
     | 
    
         
            +
                        p = PROXY()
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @inputs[input] = @pipelines[input] = Pipeline.new(input, input: p, output: p.buffered, pipelines: @pipelines)
         
     | 
| 
       27 
34 
     | 
    
         | 
| 
       28 
35 
     | 
    
         
             
                        @dsl.define_singleton_method(input) { input }
         
     | 
| 
       29 
36 
     | 
    
         
             
                      end
         
     | 
| 
       30 
37 
     | 
    
         | 
| 
       31 
38 
     | 
    
         
             
                      outputs&.each do |output|
         
     | 
| 
       32 
     | 
    
         
            -
                         
     | 
| 
       33 
     | 
    
         
            -
                        @pipelines[output] =  
     | 
| 
      
 39 
     | 
    
         
            +
                        p = PROXY()
         
     | 
| 
      
 40 
     | 
    
         
            +
                        @outputs[output] = @pipelines[output] = Pipeline.new(output, is_output: true, input: p, output: p, pipelines: @pipelines)
         
     | 
| 
       34 
41 
     | 
    
         | 
| 
       35 
42 
     | 
    
         
             
                        @dsl.define_singleton_method(output) { output }
         
     | 
| 
       36 
43 
     | 
    
         
             
                      end
         
     | 
| 
       37 
44 
     | 
    
         | 
| 
       38 
45 
     | 
    
         
             
                      @dsl.with &block if block
         
     | 
| 
      
 46 
     | 
    
         
            +
                      commit! if auto_commit
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def input(name = nil)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      name ||= :input
         
     | 
| 
      
 51 
     | 
    
         
            +
                      @inputs[name].input
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    def output(name = nil)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      raise "Can't access output if the Composer is uncommited. Call '.commit' first." unless @commited
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                      name ||= :output
         
     | 
| 
      
 58 
     | 
    
         
            +
                      @outputs[name].output
         
     | 
| 
       39 
59 
     | 
    
         
             
                    end
         
     | 
| 
       40 
60 
     | 
    
         | 
| 
       41 
61 
     | 
    
         
             
                    def route(from, to:, on: nil, as: nil)
         
     | 
| 
         @@ -50,15 +70,76 @@ module Musa 
     | 
|
| 
       50 
70 
     | 
    
         
             
                      @dsl.with &block
         
     | 
| 
       51 
71 
     | 
    
         
             
                    end
         
     | 
| 
       52 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
                    def commit!
         
     | 
| 
      
 74 
     | 
    
         
            +
                      raise 'Already commited' if @commited
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                      @outputs.each_value do |pipeline|
         
     | 
| 
      
 77 
     | 
    
         
            +
                        pipeline.commit!
         
     | 
| 
      
 78 
     | 
    
         
            +
                      end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                      @commited = true
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                    class Pipeline
         
     | 
| 
      
 84 
     | 
    
         
            +
                      def initialize(name, is_output: false, input: nil, output: nil, first_proc: nil, chain_proc: nil, pipelines:)
         
     | 
| 
      
 85 
     | 
    
         
            +
                        @name = name
         
     | 
| 
      
 86 
     | 
    
         
            +
                        @is_output = is_output
         
     | 
| 
      
 87 
     | 
    
         
            +
                        @input = input
         
     | 
| 
      
 88 
     | 
    
         
            +
                        @output = output
         
     | 
| 
      
 89 
     | 
    
         
            +
                        @first_proc = first_proc
         
     | 
| 
      
 90 
     | 
    
         
            +
                        @chain_proc = chain_proc
         
     | 
| 
      
 91 
     | 
    
         
            +
                        @routes = {}
         
     | 
| 
      
 92 
     | 
    
         
            +
                        @pipelines = pipelines
         
     | 
| 
      
 93 
     | 
    
         
            +
                      end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                      attr_reader :name, :is_output
         
     | 
| 
      
 96 
     | 
    
         
            +
                      attr_accessor :input, :output, :proc
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                      def [](on, as)
         
     | 
| 
      
 99 
     | 
    
         
            +
                        @routes[[on, as]]
         
     | 
| 
      
 100 
     | 
    
         
            +
                      end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                      def []=(on, as, source)
         
     | 
| 
      
 103 
     | 
    
         
            +
                        @routes[[on, as]] = Route.new(on, as, source)
         
     | 
| 
      
 104 
     | 
    
         
            +
                      end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                      def commit!
         
     | 
| 
      
 107 
     | 
    
         
            +
                        first_serie_operation = @first_proc&.call(NIL())
         
     | 
| 
      
 108 
     | 
    
         
            +
                        @input ||= first_serie_operation
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                        @routes.each_value do |route|
         
     | 
| 
      
 111 
     | 
    
         
            +
                          route.source.commit!
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                          if @is_output
         
     | 
| 
      
 114 
     | 
    
         
            +
                            @input.proxy_source = route.source.output.buffer
         
     | 
| 
      
 115 
     | 
    
         
            +
                          elsif route.as
         
     | 
| 
      
 116 
     | 
    
         
            +
                            @input.send(route.on)[route.as] = route.source.output.buffer
         
     | 
| 
      
 117 
     | 
    
         
            +
                          else
         
     | 
| 
      
 118 
     | 
    
         
            +
                            @input.send("#{route.on.to_s}=".to_sym, route.source.output.buffer)
         
     | 
| 
      
 119 
     | 
    
         
            +
                          end
         
     | 
| 
      
 120 
     | 
    
         
            +
                        end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                        chain_serie_operation = @chain_proc&.call(@input) || @input
         
     | 
| 
      
 123 
     | 
    
         
            +
                        @output ||= chain_serie_operation.buffered
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                        self
         
     | 
| 
      
 126 
     | 
    
         
            +
                      end
         
     | 
| 
      
 127 
     | 
    
         
            +
                    end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                    class Route
         
     | 
| 
      
 130 
     | 
    
         
            +
                      def initialize(on, as, source)
         
     | 
| 
      
 131 
     | 
    
         
            +
                        @on = on
         
     | 
| 
      
 132 
     | 
    
         
            +
                        @as = as
         
     | 
| 
      
 133 
     | 
    
         
            +
                        @source = source
         
     | 
| 
      
 134 
     | 
    
         
            +
                      end
         
     | 
| 
      
 135 
     | 
    
         
            +
                      attr_accessor :on, :as, :source
         
     | 
| 
      
 136 
     | 
    
         
            +
                    end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
       53 
138 
     | 
    
         
             
                    class DSLContext
         
     | 
| 
       54 
139 
     | 
    
         
             
                      include Musa::Extension::With
         
     | 
| 
       55 
140 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                      def initialize(pipelines 
     | 
| 
      
 141 
     | 
    
         
            +
                      def initialize(pipelines)
         
     | 
| 
       57 
142 
     | 
    
         
             
                        @pipelines = pipelines
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                        @links = links
         
     | 
| 
       60 
     | 
    
         
            -
                        @links_from = links_from
         
     | 
| 
       61 
     | 
    
         
            -
                        @links_to = links_to
         
     | 
| 
       62 
143 
     | 
    
         
             
                      end
         
     | 
| 
       63 
144 
     | 
    
         | 
| 
       64 
145 
     | 
    
         
             
                      def route(from, to:, on: nil, as: nil)
         
     | 
| 
         @@ -68,69 +149,159 @@ module Musa 
     | 
|
| 
       68 
149 
     | 
    
         
             
                        raise ArgumentError, "Pipeline '#{from}' not found." unless from_pipeline
         
     | 
| 
       69 
150 
     | 
    
         
             
                        raise ArgumentError, "Pipeline '#{to}' not found." unless to_pipeline
         
     | 
| 
       70 
151 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                         
     | 
| 
      
 152 
     | 
    
         
            +
                        if to_pipeline.is_output && (on || as)
         
     | 
| 
      
 153 
     | 
    
         
            +
                          raise ArgumentError, "Output pipeline #{to_pipeline.name} only allows default routing"
         
     | 
| 
      
 154 
     | 
    
         
            +
                        end
         
     | 
| 
       72 
155 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
                        on ||= as ? :sources : :source
         
     | 
| 
      
 156 
     | 
    
         
            +
                        on ||= (as ? :sources : :source)
         
     | 
| 
       74 
157 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
                        raise ArgumentError, 
     | 
| 
      
 158 
     | 
    
         
            +
                        raise ArgumentError,
         
     | 
| 
      
 159 
     | 
    
         
            +
                              "Source of pipeline #{to} on #{on} as #{as} already connected to #{to_pipeline[on, as].source.name}" \
         
     | 
| 
      
 160 
     | 
    
         
            +
                              unless to_pipeline[on, as].nil?
         
     | 
| 
       76 
161 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
                        if as
         
     | 
| 
       78 
     | 
    
         
            -
                          to_pipeline[:input].send(on)[as] = from_pipeline[:output].buffer
         
     | 
| 
       79 
     | 
    
         
            -
                        else
         
     | 
| 
       80 
     | 
    
         
            -
                          to_pipeline[:input].send("#{on.to_s}=".to_sym, from_pipeline[:output].buffer)
         
     | 
| 
       81 
     | 
    
         
            -
                        end
         
     | 
| 
       82 
162 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                         
     | 
| 
       84 
     | 
    
         
            -
                        @links_to[[to, on, as]] = from
         
     | 
| 
       85 
     | 
    
         
            -
                        @links << [from, to, on, as]
         
     | 
| 
      
 163 
     | 
    
         
            +
                        to_pipeline[on, as] = from_pipeline
         
     | 
| 
       86 
164 
     | 
    
         
             
                      end
         
     | 
| 
       87 
165 
     | 
    
         | 
| 
       88 
166 
     | 
    
         
             
                      def pipeline(name, elements)
         
     | 
| 
       89 
     | 
    
         
            -
                        first  
     | 
| 
      
 167 
     | 
    
         
            +
                        first, chain = parse(elements)
         
     | 
| 
      
 168 
     | 
    
         
            +
                        @pipelines[name] = Pipeline.new(name, first_proc: first, chain_proc: chain, pipelines: @pipelines)
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                        define_singleton_method(name) { name }
         
     | 
| 
      
 171 
     | 
    
         
            +
                      end
         
     | 
| 
       90 
172 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
      
 173 
     | 
    
         
            +
                      private def parse(thing)
         
     | 
| 
      
 174 
     | 
    
         
            +
                        case thing
         
     | 
| 
      
 175 
     | 
    
         
            +
                        when Array
         
     | 
| 
      
 176 
     | 
    
         
            +
                          first = chain = nil
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                          thing.each do |element|
         
     | 
| 
      
 179 
     | 
    
         
            +
                            case element
         
     | 
| 
      
 180 
     | 
    
         
            +
                            when Hash
         
     | 
| 
      
 181 
     | 
    
         
            +
                              new_chain = parse(element)
         
     | 
| 
      
 182 
     | 
    
         
            +
                            when Symbol
         
     | 
| 
      
 183 
     | 
    
         
            +
                              new_chain = operation_as_chained_proc(element, nil)
         
     | 
| 
      
 184 
     | 
    
         
            +
                            when Proc
         
     | 
| 
      
 185 
     | 
    
         
            +
                              new_chain = operation_as_chained_proc(:map, element)
         
     | 
| 
      
 186 
     | 
    
         
            +
                            else
         
     | 
| 
      
 187 
     | 
    
         
            +
                              raise ArgumentError, "Syntax error: don't know how to handle #{element}"
         
     | 
| 
      
 188 
     | 
    
         
            +
                            end
         
     | 
| 
       97 
189 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
      
 190 
     | 
    
         
            +
                            if first.nil?
         
     | 
| 
      
 191 
     | 
    
         
            +
                              first = new_chain unless first
         
     | 
| 
      
 192 
     | 
    
         
            +
                            else
         
     | 
| 
      
 193 
     | 
    
         
            +
                              chain = chain ? chain >> new_chain : new_chain
         
     | 
| 
      
 194 
     | 
    
         
            +
                            end
         
     | 
| 
      
 195 
     | 
    
         
            +
                          end
         
     | 
| 
       100 
196 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
      
 197 
     | 
    
         
            +
                          [first, chain]
         
     | 
| 
       102 
198 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
      
 199 
     | 
    
         
            +
                        when Hash
         
     | 
| 
      
 200 
     | 
    
         
            +
                          if thing.size == 1
         
     | 
| 
      
 201 
     | 
    
         
            +
                            operation = thing.first[0] # key
         
     | 
| 
      
 202 
     | 
    
         
            +
                            parameter = thing.first[1] # value
         
     | 
| 
       106 
203 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
      
 204 
     | 
    
         
            +
                            if is_a_series_constructor?(operation)
         
     | 
| 
      
 205 
     | 
    
         
            +
                              operation_as_chained_proc(operation, parameter)
         
     | 
| 
       108 
206 
     | 
    
         
             
                            else
         
     | 
| 
       109 
     | 
    
         
            -
                               
     | 
| 
      
 207 
     | 
    
         
            +
                              operation_as_chained_proc(operation, parse(parameter))
         
     | 
| 
       110 
208 
     | 
    
         
             
                            end
         
     | 
| 
       111 
     | 
    
         
            -
                           
     | 
| 
       112 
     | 
    
         
            -
                             
     | 
| 
       113 
     | 
    
         
            -
                            # operation == e
         
     | 
| 
       114 
     | 
    
         
            -
                            last = last.send(e) if Musa::Series::Operations.instance_methods.include?(e)
         
     | 
| 
      
 209 
     | 
    
         
            +
                          else
         
     | 
| 
      
 210 
     | 
    
         
            +
                            raise ArgumentError, "Syntax error: don't know how to handle #{element}"
         
     | 
| 
       115 
211 
     | 
    
         
             
                          end
         
     | 
| 
       116 
212 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
      
 213 
     | 
    
         
            +
                        when Symbol
         
     | 
| 
      
 214 
     | 
    
         
            +
                          operation_as_chained_proc(operation)
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                        when Proc
         
     | 
| 
      
 217 
     | 
    
         
            +
                          thing
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
                        else
         
     | 
| 
      
 220 
     | 
    
         
            +
                          thing
         
     | 
| 
       118 
221 
     | 
    
         
             
                        end
         
     | 
| 
      
 222 
     | 
    
         
            +
                      end
         
     | 
| 
       119 
223 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
      
 224 
     | 
    
         
            +
                      private def operation_as_chained_proc(operation, parameter = nil)
         
     | 
| 
      
 225 
     | 
    
         
            +
                        if is_a_series_constructor?(operation)
         
     | 
| 
      
 226 
     | 
    
         
            +
                          proc do |last|
         
     | 
| 
      
 227 
     | 
    
         
            +
                            call_constructor_according_to_last_and_parameter(last, operation, parameter)
         
     | 
| 
      
 228 
     | 
    
         
            +
                          end
         
     | 
| 
       121 
229 
     | 
    
         | 
| 
       122 
     | 
    
         
            -
                         
     | 
| 
      
 230 
     | 
    
         
            +
                        elsif is_a_series_operation?(operation)
         
     | 
| 
      
 231 
     | 
    
         
            +
                          proc { |last| call_operation_according_to_parameter(last, operation, parameter) }
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
                        else
         
     | 
| 
      
 234 
     | 
    
         
            +
                          # non-series operation
         
     | 
| 
      
 235 
     | 
    
         
            +
                          proc { |last| call_operation_according_to_parameter(last, operation, parameter) }
         
     | 
| 
      
 236 
     | 
    
         
            +
                        end
         
     | 
| 
       123 
237 
     | 
    
         
             
                      end
         
     | 
| 
       124 
238 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
                      private def  
     | 
| 
       126 
     | 
    
         
            -
                         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
      
 239 
     | 
    
         
            +
                      private def call_constructor_according_to_last_and_parameter(last, constructor, parameter)
         
     | 
| 
      
 240 
     | 
    
         
            +
                        case last
         
     | 
| 
      
 241 
     | 
    
         
            +
                        when Proc
         
     | 
| 
      
 242 
     | 
    
         
            +
                          call_constructor_according_to_last_and_parameter(last.call, constructor, parameter)
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                        when Serie
         
     | 
| 
      
 245 
     | 
    
         
            +
                          # TODO: ignoring last, should make an error?
         
     | 
| 
      
 246 
     | 
    
         
            +
                          Musa::Series::Constructors.method(constructor).call(*parameter)
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
                        when nil
         
     | 
| 
      
 249 
     | 
    
         
            +
                          Musa::Series::Constructors.method(constructor).call(*parameter)
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                        when Array
         
     | 
| 
      
 252 
     | 
    
         
            +
                          raise "Unexpected parameter #{parameter} for constructor #{constructor} " \
         
     | 
| 
      
 253 
     | 
    
         
            +
                            "because the previous operation on the pipeline chain returned non-nil #{last}" \
         
     | 
| 
      
 254 
     | 
    
         
            +
                            unless parameter.nil?
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                          Musa::Series::Constructors.method(constructor).call(*last)
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
                        when Hash
         
     | 
| 
      
 259 
     | 
    
         
            +
                          raise "Unexpected parameter #{parameter} for constructor #{constructor} " \
         
     | 
| 
      
 260 
     | 
    
         
            +
                            "because the previous operation on the pipeline chain returned non-nil #{last}" \
         
     | 
| 
      
 261 
     | 
    
         
            +
                            unless parameter.nil?
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
                          Musa::Series::Constructors.method(constructor).call(**last)
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                        else
         
     | 
| 
      
 266 
     | 
    
         
            +
                          raise ArgumentError, "Don't know how to handle last #{last}"
         
     | 
| 
      
 267 
     | 
    
         
            +
                        end
         
     | 
| 
      
 268 
     | 
    
         
            +
                      end
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
                      private def call_operation_according_to_parameter(target, operation, parameter)
         
     | 
| 
      
 271 
     | 
    
         
            +
                        case parameter
         
     | 
| 
      
 272 
     | 
    
         
            +
                        when nil
         
     | 
| 
      
 273 
     | 
    
         
            +
                          target.send(operation)
         
     | 
| 
      
 274 
     | 
    
         
            +
                        when Symbol
         
     | 
| 
      
 275 
     | 
    
         
            +
                          target.send(operation).send(parameter)
         
     | 
| 
      
 276 
     | 
    
         
            +
                        when Proc
         
     | 
| 
      
 277 
     | 
    
         
            +
                          target.send(operation, ¶meter)
         
     | 
| 
      
 278 
     | 
    
         
            +
                        when Array
         
     | 
| 
      
 279 
     | 
    
         
            +
                          unless parameter.size == 2 && parameter.all? { |_| _.is_a?(Proc) }
         
     | 
| 
      
 280 
     | 
    
         
            +
                            raise ArgumentError, "Don't know how to handle parameter #{parameter}"
         
     | 
| 
      
 281 
     | 
    
         
            +
                          end
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
                          target.send(operation, &(parameter.first >> parameter.last))
         
     | 
| 
       130 
284 
     | 
    
         
             
                        else
         
     | 
| 
       131 
     | 
    
         
            -
                           
     | 
| 
      
 285 
     | 
    
         
            +
                          target.send(operation, parameter)
         
     | 
| 
      
 286 
     | 
    
         
            +
                        end
         
     | 
| 
      
 287 
     | 
    
         
            +
                      end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                      private def is_a_series_constructor?(operation)
         
     | 
| 
      
 290 
     | 
    
         
            +
                        Musa::Series::Constructors.instance_methods.include?(operation)
         
     | 
| 
      
 291 
     | 
    
         
            +
                      end
         
     | 
| 
       132 
292 
     | 
    
         | 
| 
      
 293 
     | 
    
         
            +
                      private def is_a_series_operation?(operation)
         
     | 
| 
      
 294 
     | 
    
         
            +
                        Musa::Series::Operations.instance_methods.include?(operation)
         
     | 
| 
      
 295 
     | 
    
         
            +
                      end
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                      private def method_missing(symbol, *args, &block)
         
     | 
| 
      
 298 
     | 
    
         
            +
                        if is_a_series_constructor?(symbol) || is_a_series_operation?(symbol)
         
     | 
| 
      
 299 
     | 
    
         
            +
                          symbol
         
     | 
| 
      
 300 
     | 
    
         
            +
                        elsif args.any? || block
         
     | 
| 
      
 301 
     | 
    
         
            +
                          args += [block] if block
         
     | 
| 
       133 
302 
     | 
    
         
             
                          pipeline(symbol, args)
         
     | 
| 
      
 303 
     | 
    
         
            +
                        else # for non-series methods
         
     | 
| 
      
 304 
     | 
    
         
            +
                          symbol
         
     | 
| 
       134 
305 
     | 
    
         
             
                        end
         
     | 
| 
       135 
306 
     | 
    
         
             
                      end
         
     | 
| 
       136 
307 
     | 
    
         | 
| 
         @@ -142,6 +313,8 @@ module Musa 
     | 
|
| 
       142 
313 
     | 
    
         
             
                      end
         
     | 
| 
       143 
314 
     | 
    
         
             
                    end
         
     | 
| 
       144 
315 
     | 
    
         | 
| 
      
 316 
     | 
    
         
            +
                    private_constant :Pipeline
         
     | 
| 
      
 317 
     | 
    
         
            +
                    private_constant :Route
         
     | 
| 
       145 
318 
     | 
    
         
             
                    private_constant :DSLContext
         
     | 
| 
       146 
319 
     | 
    
         
             
                  end
         
     | 
| 
       147 
320 
     | 
    
         
             
                end
         
     | 
    
        data/musa-dsl.gemspec
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Gem::Specification.new do |s|
         
     | 
| 
       2 
2 
     | 
    
         
             
              s.name        = 'musa-dsl'
         
     | 
| 
       3 
     | 
    
         
            -
              s.version     = '0.23. 
     | 
| 
       4 
     | 
    
         
            -
              s.date        = '2021- 
     | 
| 
      
 3 
     | 
    
         
            +
              s.version     = '0.23.5'
         
     | 
| 
      
 4 
     | 
    
         
            +
              s.date        = '2021-07-28'
         
     | 
| 
       5 
5 
     | 
    
         
             
              s.summary     = 'A simple Ruby DSL for making complex music'
         
     | 
| 
       6 
6 
     | 
    
         
             
              s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
         
     | 
| 
       7 
7 
     | 
    
         
             
              s.authors     = ['Javier Sánchez Yeste']
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: musa-dsl
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.23. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.23.5
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Javier Sánchez Yeste
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-07-28 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: citrus
         
     |