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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4a1fb5e2fc74d27266ed15f6edcc335c61b580f3c8fa83fd2c425066230a42b
4
- data.tar.gz: 5778babbeeab02ea23d511369946990209929b284e0025f65a67602a1c8fa504
3
+ metadata.gz: 19683437b5ef89739c0d1283c86b18c547a24dd058ca5013abdea4f9c6335f5c
4
+ data.tar.gz: 99fea2b0076baf8976050bd9467f4ecafb87a44bad1b37933e741116f1f5ec96
5
5
  SHA512:
6
- metadata.gz: 33c4b5ab4b14c941ed36ede8919961f0c9bc4d0ec6acf34f2b02f297483c17dfb2e23d270118143c7199f2e073cf001591ad393cae09cbc41e75ac20d8f82c7a
7
- data.tar.gz: 4ffcea9a0a82bd7f97ef659ba0a3b03d9b319980df8987986ee0f63eb694d144fc03d0299b3a87665b78a52fafb5d9b840cf10e7461f36cbfe58b30ce4712f22
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 :log
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 sequencer: @sequencer, output: @output, channel: channel, log: @do_log }.freeze
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, log: nil)
52
- log ||= false
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 = 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
- log 'Warning: voice without output' unless @output
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.log "voice #{name || @channel}: #{msg}" if @do_log
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 source should be a #{@get}" unless @source.nil? || @source.prototype? == serie&.prototype?
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(recursive: nil, duplicate: nil, restart: nil, dr: nil)
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(main)
121
- raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless main
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 { |_| _ > main.index }
124
+ next_nil = @nils.find { |_| _ > buffer.index }
125
125
 
126
- if next_nil && main.index < next_nil
127
- main.last_nil_index = main.index = next_nil
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
- main.last_nil_index = main.index = @nils.last
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(Splitter::BufferedProxy.new(self))
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(proxy)
11
- @proxy = proxy
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
- if @series.has_key?(key_or_index)
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 BufferedProxy
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
- mark_regarding! @source
69
-
70
- init
81
+ infer_components
71
82
  end
72
83
 
73
- attr_reader :components
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
- def init
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
- @source = proxy
169
+ @proxy = proxy
155
170
  @key_or_index = key_or_index
156
171
 
157
- mark_regarding! @source
172
+ mark_as_instance!
158
173
  end
159
174
 
160
175
  private def _restart
161
- @source.restart @key_or_index
176
+ @proxy.restart(@key_or_index)
162
177
  end
163
178
 
164
179
  private def _next_value
165
- @source.next_value(@key_or_index)
180
+ @proxy.next_value(@key_or_index)
166
181
  end
167
182
  end
168
183
 
@@ -566,7 +566,7 @@ module Musa
566
566
  end
567
567
 
568
568
  private def _next_value
569
- unless @have_current && @value.nil?
569
+ unless @sources.empty? || @have_current && @value.nil?
570
570
  pre_value = @sources.collect(&:peek_next_value)
571
571
 
572
572
  nils = 0
@@ -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.source = serie
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 && @source.respond_to?(method_name)
31
- @source.send method_name, *args, **key_args, &block
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
- attr_reader :inputs, :outputs
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
- @links = Set[]
17
- @links_from = {}
18
- @links_to = {}
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, @links, @links_from, @links_to)
27
+ @dsl = DSLContext.new(@pipelines)
21
28
  @inputs = {}
22
29
  @outputs = {}
23
30
 
24
31
  inputs&.each do |input|
25
- @inputs[input] = Series::Constructors.PROXY
26
- @pipelines[input] = { input: nil, output: @inputs[input].buffered }
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
- @outputs[output] = Series::Constructors.PROXY
33
- @pipelines[output] = { input: @outputs[output], output: nil }
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, links, links_from, links_to)
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
- @links_from[from] ||= Set[]
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, "Pipeline #{@links_to[[to, on, as]]} already connected to pipeline #{to} on #{on} as #{as}" if @links_to[[to, on, as]]
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
- @links_from[from] << [to, on, as]
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 = last = nil
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
- elements.each do |e|
92
- case e
93
- when Hash
94
- if e.size == 1
95
- operation = e.keys.first
96
- parameters = e.values.first
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
- if Musa::Series::Constructors.instance_methods.include?(operation)
99
- raise ArgumentError, "Called constructor '#{operation}' ignoring previous elements" unless last.nil?
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
- last = Musa::Series::Constructors.method(operation).call(*parameters)
197
+ [first, chain]
102
198
 
103
- elsif Musa::Series::Operations.instance_methods.include?(operation)
104
- first = last = Musa::Series::Constructors.PROXY if last.nil?
105
- last = last.send(operation, *parameters)
199
+ when Hash
200
+ if thing.size == 1
201
+ operation = thing.first[0] # key
202
+ parameter = thing.first[1] # value
106
203
 
107
- end
204
+ if is_a_series_constructor?(operation)
205
+ operation_as_chained_proc(operation, parameter)
108
206
  else
109
- raise ArgumentError, "Don't know how to handle #{e}"
207
+ operation_as_chained_proc(operation, parse(parameter))
110
208
  end
111
- when Symbol
112
- first = last = Musa::Series::Constructors.PROXY if last.nil?
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
- first ||= last
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
- @pipelines[name] = { input: first, output: last.buffered }
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
- define_singleton_method(name) { name }
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 method_missing(symbol, *args, &block)
126
- if Musa::Series::Operations.instance_methods.include?(symbol)
127
- symbol
128
- elsif Musa::Series::Constructors.instance_methods.include?(symbol)
129
- symbol
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, &parameter)
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
- raise ArgumentError, "Pipeline '#{symbol}' is undefined" if args.empty?
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.0'
4
- s.date = '2021-06-29'
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.0
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-06-29 00:00:00.000000000 Z
11
+ date: 2021-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: citrus