musa-dsl 0.22.5 → 0.23.3
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/Gemfile +3 -1
- data/lib/musa-dsl.rb +14 -8
- data/lib/musa-dsl/core-ext/deep-copy.rb +12 -1
- data/lib/musa-dsl/core-ext/inspect-nice.rb +1 -2
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +13 -11
- data/lib/musa-dsl/datasets/p.rb +38 -15
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +14 -12
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +32 -6
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +24 -10
- data/lib/musa-dsl/generative/backboner.rb +6 -11
- data/lib/musa-dsl/generative/generative-grammar.rb +1 -3
- data/lib/musa-dsl/generative/markov.rb +10 -6
- data/lib/musa-dsl/logger/logger.rb +6 -1
- data/lib/musa-dsl/midi/midi-voices.rb +8 -7
- data/lib/musa-dsl/music/scales.rb +1 -1
- data/lib/musa-dsl/neumalang/neumalang.rb +1 -1
- data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +2 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +2 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +2 -0
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +4 -2
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +6 -6
- data/lib/musa-dsl/series/base-series.rb +293 -144
- data/lib/musa-dsl/series/buffer-serie.rb +236 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +145 -115
- data/lib/musa-dsl/series/main-serie-constructors.rb +249 -156
- data/lib/musa-dsl/series/main-serie-operations.rb +331 -318
- data/lib/musa-dsl/series/proxy-serie.rb +25 -41
- data/lib/musa-dsl/series/quantizer-serie.rb +38 -38
- data/lib/musa-dsl/series/queue-serie.rb +39 -43
- data/lib/musa-dsl/series/series-composer.rb +316 -0
- data/lib/musa-dsl/series/series.rb +5 -1
- data/lib/musa-dsl/series/timed-serie.rb +119 -130
- data/musa-dsl.gemspec +13 -3
- metadata +9 -9
- data/.ruby-version +0 -1
- data/lib/musa-dsl/series/holder-serie.rb +0 -87
@@ -1,6 +1,6 @@
|
|
1
1
|
module Musa
|
2
2
|
module Series
|
3
|
-
module
|
3
|
+
module Operations
|
4
4
|
def autorestart
|
5
5
|
Autorestart.new self
|
6
6
|
end
|
@@ -108,12 +108,16 @@ module Musa
|
|
108
108
|
|
109
109
|
alias_method :eval, :with
|
110
110
|
|
111
|
-
def map(&
|
112
|
-
ProcessWith.new self, &
|
111
|
+
def map(&block)
|
112
|
+
ProcessWith.new self, &block
|
113
113
|
end
|
114
114
|
|
115
|
-
def anticipate(&
|
116
|
-
Anticipate.new self, &
|
115
|
+
def anticipate(&block)
|
116
|
+
Anticipate.new self, &block
|
117
|
+
end
|
118
|
+
|
119
|
+
def lazy(&block)
|
120
|
+
LazySerieEval.new self, &block
|
117
121
|
end
|
118
122
|
|
119
123
|
###
|
@@ -121,34 +125,36 @@ module Musa
|
|
121
125
|
###
|
122
126
|
|
123
127
|
class ProcessWith
|
124
|
-
include
|
125
|
-
include Serie
|
126
|
-
|
127
|
-
attr_reader :source, :on_restart, :block
|
128
|
-
def with_sources; @sources; end
|
128
|
+
include Serie.with(source: true, sources: true, sources_as: :with_sources, smart_block: true)
|
129
129
|
|
130
130
|
def initialize(serie, with_series = nil, on_restart = nil, &block)
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
131
|
+
self.source = serie
|
132
|
+
self.with_sources = with_series || {}
|
133
|
+
self.on_restart = on_restart
|
134
|
+
self.proc = block if block
|
135
135
|
|
136
|
-
|
137
|
-
|
136
|
+
init
|
137
|
+
end
|
138
|
+
|
139
|
+
def on_restart(&block)
|
140
|
+
if block
|
141
|
+
@on_restart = block
|
138
142
|
else
|
139
|
-
@
|
143
|
+
@on_restart
|
140
144
|
end
|
145
|
+
end
|
141
146
|
|
142
|
-
|
147
|
+
def on_restart=(block)
|
148
|
+
@on_restart = block
|
143
149
|
end
|
144
150
|
|
145
|
-
def _restart
|
151
|
+
private def _restart
|
146
152
|
@source.restart
|
147
|
-
@sources.values.each
|
153
|
+
@sources.values.each(&:restart)
|
148
154
|
@on_restart.call if @on_restart
|
149
155
|
end
|
150
156
|
|
151
|
-
def _next_value
|
157
|
+
private def _next_value
|
152
158
|
main = @source.next_value
|
153
159
|
others = @sources.transform_values { |v| v.next_value }
|
154
160
|
|
@@ -173,27 +179,29 @@ module Musa
|
|
173
179
|
private_constant :ProcessWith
|
174
180
|
|
175
181
|
class Anticipate
|
176
|
-
include
|
177
|
-
include Serie
|
178
|
-
|
179
|
-
attr_reader :source, :block
|
182
|
+
include Serie.with(source: true, block: true)
|
180
183
|
|
181
184
|
def initialize(serie, &block)
|
182
|
-
|
183
|
-
|
185
|
+
self.source = serie
|
186
|
+
self.proc = block
|
184
187
|
|
185
|
-
|
188
|
+
init
|
186
189
|
end
|
187
190
|
|
188
|
-
def _restart
|
191
|
+
private def _restart
|
189
192
|
@source.restart
|
190
193
|
end
|
191
194
|
|
192
|
-
def _next_value
|
195
|
+
private def _next_value
|
196
|
+
previous_value = @source.current_value
|
193
197
|
value = @source.next_value
|
194
198
|
peek_next_value = @source.peek_next_value
|
195
199
|
|
196
|
-
|
200
|
+
if value.nil?
|
201
|
+
nil
|
202
|
+
else
|
203
|
+
@block.call(previous_value, value, peek_next_value)
|
204
|
+
end
|
197
205
|
end
|
198
206
|
|
199
207
|
def infinite?
|
@@ -204,30 +212,16 @@ module Musa
|
|
204
212
|
private_constant :Anticipate
|
205
213
|
|
206
214
|
class Switcher
|
207
|
-
include Serie
|
208
|
-
|
209
|
-
attr_accessor :sources
|
210
|
-
def selector; @source; end
|
215
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
211
216
|
|
212
217
|
def initialize(selector, indexed_series, hash_series)
|
218
|
+
self.source = selector
|
219
|
+
self.options = indexed_series || hash_series
|
213
220
|
|
214
|
-
|
215
|
-
get = @source.prototype? ? :prototype : :instance
|
216
|
-
|
217
|
-
if indexed_series && !indexed_series.empty?
|
218
|
-
@sources = indexed_series.collect(&get)
|
219
|
-
elsif hash_series && !hash_series.empty?
|
220
|
-
@sources = hash_series.clone.transform_values(&get)
|
221
|
-
end
|
222
|
-
|
223
|
-
if get == :prototype!
|
224
|
-
@sources.freeze
|
225
|
-
end
|
226
|
-
|
227
|
-
mark_regarding! @source
|
221
|
+
init
|
228
222
|
end
|
229
223
|
|
230
|
-
def _restart
|
224
|
+
private def _restart
|
231
225
|
@source.restart
|
232
226
|
if @sources.is_a? Array
|
233
227
|
@sources.each(&:restart)
|
@@ -236,7 +230,7 @@ module Musa
|
|
236
230
|
end
|
237
231
|
end
|
238
232
|
|
239
|
-
def _next_value
|
233
|
+
private def _next_value
|
240
234
|
value = nil
|
241
235
|
|
242
236
|
index_or_key = @source.next_value
|
@@ -254,46 +248,31 @@ module Musa
|
|
254
248
|
private_constant :Switcher
|
255
249
|
|
256
250
|
class MultiplexSelector
|
257
|
-
include Serie
|
258
|
-
|
259
|
-
def selector; @source; end
|
260
|
-
attr_accessor :sources
|
251
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
261
252
|
|
262
253
|
def initialize(selector, indexed_series, hash_series)
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
if indexed_series && !indexed_series.empty?
|
267
|
-
@sources = indexed_series.collect(&get)
|
268
|
-
elsif hash_series && !hash_series.empty?
|
269
|
-
@sources = hash_series.clone.transform_values(&get)
|
270
|
-
end
|
271
|
-
|
272
|
-
_restart false
|
254
|
+
self.source = selector
|
255
|
+
self.options = indexed_series || hash_series
|
273
256
|
|
274
|
-
|
275
|
-
@sources.freeze
|
276
|
-
end
|
277
|
-
|
278
|
-
mark_regarding! @source
|
257
|
+
init
|
279
258
|
end
|
280
259
|
|
281
|
-
def
|
260
|
+
private def _init
|
282
261
|
@current_value = nil
|
262
|
+
@first = true
|
263
|
+
end
|
283
264
|
|
284
|
-
|
285
|
-
|
286
|
-
if @sources.is_a? Array
|
287
|
-
@sources.each(&:restart)
|
288
|
-
elsif @sources.is_a? Hash
|
289
|
-
@sources.each { |_key, serie| serie.restart }
|
290
|
-
end
|
291
|
-
end
|
265
|
+
private def _restart
|
266
|
+
@source.restart
|
292
267
|
|
293
|
-
@
|
268
|
+
if @sources.is_a? Array
|
269
|
+
@sources.each(&:restart)
|
270
|
+
elsif @sources.is_a? Hash
|
271
|
+
@sources.values.each(&:restart)
|
272
|
+
end
|
294
273
|
end
|
295
274
|
|
296
|
-
def _next_value
|
275
|
+
private def _next_value
|
297
276
|
@current_value =
|
298
277
|
if @first || !@current_value.nil?
|
299
278
|
@first = false
|
@@ -313,34 +292,21 @@ module Musa
|
|
313
292
|
private_constant :MultiplexSelector
|
314
293
|
|
315
294
|
class SwitchFullSerie
|
316
|
-
include Serie
|
317
|
-
|
318
|
-
def selector; @source; end
|
319
|
-
attr_accessor :sources
|
295
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
320
296
|
|
321
297
|
def initialize(selector, indexed_series, hash_series)
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
if indexed_series && !indexed_series.empty?
|
326
|
-
@sources = indexed_series.collect(&get)
|
327
|
-
elsif hash_series && !hash_series.empty?
|
328
|
-
@sources = hash_series.clone.transform_values(&get)
|
329
|
-
end
|
330
|
-
|
331
|
-
if get == :prototype
|
332
|
-
@sources.freeze
|
333
|
-
end
|
298
|
+
self.source = selector
|
299
|
+
self.options = indexed_series || hash_series
|
334
300
|
|
335
|
-
|
301
|
+
init
|
336
302
|
end
|
337
303
|
|
338
|
-
def _restart
|
304
|
+
private def _restart
|
339
305
|
@source.restart
|
340
306
|
@sources.each(&:restart)
|
341
307
|
end
|
342
308
|
|
343
|
-
def _next_value
|
309
|
+
private def _next_value
|
344
310
|
value = nil
|
345
311
|
|
346
312
|
value = @sources[@index_or_key].next_value unless @index_or_key.nil?
|
@@ -362,21 +328,18 @@ module Musa
|
|
362
328
|
private_constant :SwitchFullSerie
|
363
329
|
|
364
330
|
class InfiniteRepeater
|
365
|
-
include Serie
|
366
|
-
|
367
|
-
attr_reader :source
|
331
|
+
include Serie.with(source: true)
|
368
332
|
|
369
333
|
def initialize(serie)
|
370
|
-
|
371
|
-
|
372
|
-
mark_regarding! @source
|
334
|
+
self.source = serie
|
335
|
+
init
|
373
336
|
end
|
374
337
|
|
375
|
-
def _restart
|
338
|
+
private def _restart
|
376
339
|
@source.restart
|
377
340
|
end
|
378
341
|
|
379
|
-
def _next_value
|
342
|
+
private def _next_value
|
380
343
|
value = @source.next_value
|
381
344
|
|
382
345
|
if value.nil?
|
@@ -395,38 +358,47 @@ module Musa
|
|
395
358
|
private_constant :InfiniteRepeater
|
396
359
|
|
397
360
|
class Repeater
|
398
|
-
include Serie
|
399
|
-
|
400
|
-
attr_reader :source, :times, :condition
|
361
|
+
include Serie.with(source: true)
|
401
362
|
|
402
363
|
def initialize(serie, times = nil, &condition)
|
403
|
-
|
364
|
+
self.source = serie
|
365
|
+
self.times = times
|
366
|
+
self.condition = condition
|
404
367
|
|
405
|
-
|
406
|
-
|
368
|
+
init
|
369
|
+
end
|
407
370
|
|
408
|
-
|
409
|
-
@condition = calculate_condition
|
371
|
+
attr_reader :times
|
410
372
|
|
411
|
-
|
373
|
+
def times=(value)
|
374
|
+
@times = value
|
375
|
+
calculate_condition
|
412
376
|
end
|
413
377
|
|
414
|
-
def
|
415
|
-
|
416
|
-
|
378
|
+
def condition(&block)
|
379
|
+
if block
|
380
|
+
@external_condition = block
|
381
|
+
calculate_condition
|
382
|
+
else
|
383
|
+
@external_condition
|
384
|
+
end
|
417
385
|
end
|
418
386
|
|
419
|
-
def
|
420
|
-
|
421
|
-
|
387
|
+
def condition=(block)
|
388
|
+
@external_condition = block
|
389
|
+
calculate_condition
|
422
390
|
end
|
423
391
|
|
424
|
-
def
|
392
|
+
private def _init
|
425
393
|
@count = 0
|
426
|
-
|
394
|
+
calculate_condition
|
395
|
+
end
|
396
|
+
|
397
|
+
private def _restart
|
398
|
+
@source.restart
|
427
399
|
end
|
428
400
|
|
429
|
-
def _next_value
|
401
|
+
private def _next_value
|
430
402
|
value = @source.next_value
|
431
403
|
|
432
404
|
if value.nil?
|
@@ -446,38 +418,39 @@ module Musa
|
|
446
418
|
end
|
447
419
|
|
448
420
|
private def calculate_condition
|
449
|
-
if @external_condition
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
421
|
+
@condition = if @external_condition
|
422
|
+
@external_condition
|
423
|
+
elsif @times
|
424
|
+
proc { @count < @times }
|
425
|
+
else
|
426
|
+
proc { false }
|
427
|
+
end
|
456
428
|
end
|
457
429
|
end
|
458
430
|
|
459
431
|
private_constant :Repeater
|
460
432
|
|
461
433
|
class LengthLimiter
|
462
|
-
include Serie
|
463
|
-
|
464
|
-
attr_reader :source, :length
|
434
|
+
include Serie.with(source: true)
|
465
435
|
|
466
436
|
def initialize(serie, length)
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
_restart false
|
437
|
+
self.source = serie
|
438
|
+
self.length = length
|
471
439
|
|
472
|
-
|
440
|
+
init
|
473
441
|
end
|
474
442
|
|
475
|
-
|
443
|
+
attr_accessor :length
|
444
|
+
|
445
|
+
private def _init
|
476
446
|
@position = 0
|
477
|
-
@source.restart if restart_sources
|
478
447
|
end
|
479
448
|
|
480
|
-
def
|
449
|
+
private def _restart
|
450
|
+
@source.restart
|
451
|
+
end
|
452
|
+
|
453
|
+
private def _next_value
|
481
454
|
if @position < @length
|
482
455
|
@position += 1
|
483
456
|
@source.next_value
|
@@ -492,25 +465,26 @@ module Musa
|
|
492
465
|
private_constant :LengthLimiter
|
493
466
|
|
494
467
|
class Skipper
|
495
|
-
include Serie
|
496
|
-
|
497
|
-
attr_reader :source, :length
|
468
|
+
include Serie.with(source: true)
|
498
469
|
|
499
470
|
def initialize(serie, length)
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
_restart false
|
471
|
+
self.source = serie
|
472
|
+
self.length = length
|
504
473
|
|
505
|
-
|
474
|
+
init
|
506
475
|
end
|
507
476
|
|
508
|
-
|
509
|
-
|
477
|
+
attr_accessor :length
|
478
|
+
|
479
|
+
private def _init
|
510
480
|
@first = true
|
511
481
|
end
|
512
482
|
|
513
|
-
def
|
483
|
+
private def _restart
|
484
|
+
@source.restart
|
485
|
+
end
|
486
|
+
|
487
|
+
private def _next_value
|
514
488
|
@length.times { @source.next_value } if @first
|
515
489
|
@first = nil
|
516
490
|
|
@@ -525,40 +499,25 @@ module Musa
|
|
525
499
|
private_constant :Skipper
|
526
500
|
|
527
501
|
class Flattener
|
528
|
-
include Serie
|
529
|
-
|
530
|
-
attr_reader :source
|
502
|
+
include Serie.base
|
531
503
|
|
532
504
|
def initialize(serie)
|
533
505
|
@source = serie
|
534
|
-
|
535
|
-
_restart false
|
536
|
-
|
537
506
|
mark_regarding! @source
|
507
|
+
init
|
538
508
|
end
|
539
509
|
|
540
|
-
def
|
541
|
-
|
542
|
-
|
543
|
-
end
|
544
|
-
|
545
|
-
def _instance!
|
546
|
-
super
|
547
|
-
_restart false
|
510
|
+
private def _init
|
511
|
+
@stack = [@source]
|
512
|
+
@restart_each_serie = false
|
548
513
|
end
|
549
514
|
|
550
|
-
def _restart
|
551
|
-
|
552
|
-
|
553
|
-
@restart_each_serie = true
|
554
|
-
else
|
555
|
-
@restart_each_serie = false
|
556
|
-
end
|
557
|
-
|
558
|
-
@stack = [@source]
|
515
|
+
private def _restart
|
516
|
+
@source.restart
|
517
|
+
@restart_each_serie = true
|
559
518
|
end
|
560
519
|
|
561
|
-
def _next_value
|
520
|
+
private def _next_value
|
562
521
|
if @stack.last
|
563
522
|
value = @stack.last.next_value
|
564
523
|
|
@@ -585,26 +544,24 @@ module Musa
|
|
585
544
|
private_constant :Flattener
|
586
545
|
|
587
546
|
class MergeSerieOfSeries
|
588
|
-
include Serie
|
589
|
-
|
590
|
-
attr_reader :source
|
547
|
+
include Serie.with(source: true)
|
591
548
|
|
592
549
|
def initialize(serie)
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
mark_regarding! @source
|
550
|
+
self.source = serie
|
551
|
+
init
|
597
552
|
end
|
598
553
|
|
599
|
-
def
|
600
|
-
if restart_sources
|
601
|
-
@source.restart
|
602
|
-
@restart_each_serie = true
|
603
|
-
end
|
554
|
+
private def _init
|
604
555
|
@current_serie = nil
|
556
|
+
@restart_each_serie = false
|
605
557
|
end
|
606
558
|
|
607
|
-
def
|
559
|
+
private def _restart
|
560
|
+
@source.restart
|
561
|
+
@restart_each_serie = true
|
562
|
+
end
|
563
|
+
|
564
|
+
private def _next_value
|
608
565
|
value = nil
|
609
566
|
|
610
567
|
restart_current_serie_if_needed = false
|
@@ -641,27 +598,28 @@ module Musa
|
|
641
598
|
private_constant :MergeSerieOfSeries
|
642
599
|
|
643
600
|
class Processor
|
644
|
-
include
|
645
|
-
include Serie
|
646
|
-
|
647
|
-
attr_reader :source
|
601
|
+
include Serie.with(source: true, smart_block: true)
|
648
602
|
|
649
603
|
def initialize(serie, parameters, &processor)
|
650
|
-
|
651
|
-
@parameters = parameters
|
652
|
-
@processor = SmartProcBinder.new(processor)
|
604
|
+
self.source = serie
|
653
605
|
|
654
|
-
|
606
|
+
self.parameters = parameters
|
607
|
+
self.proc = processor if processor
|
655
608
|
|
656
|
-
|
609
|
+
init
|
657
610
|
end
|
658
611
|
|
659
|
-
|
660
|
-
|
612
|
+
attr_accessor :parameters
|
613
|
+
|
614
|
+
private def _init
|
661
615
|
@pending_values = []
|
662
616
|
end
|
663
617
|
|
664
|
-
def
|
618
|
+
private def _restart
|
619
|
+
@source.restart
|
620
|
+
end
|
621
|
+
|
622
|
+
private def _next_value
|
665
623
|
if @pending_values.empty?
|
666
624
|
|
667
625
|
v = @source.next_value
|
@@ -669,7 +627,7 @@ module Musa
|
|
669
627
|
if v.nil?
|
670
628
|
nil
|
671
629
|
else
|
672
|
-
value = @
|
630
|
+
value = @block.call(v, **@parameters)
|
673
631
|
|
674
632
|
if value.is_a?(Array)
|
675
633
|
@pending_values = value
|
@@ -695,23 +653,22 @@ module Musa
|
|
695
653
|
end
|
696
654
|
|
697
655
|
class Autorestart
|
698
|
-
include Serie
|
699
|
-
|
700
|
-
attr_reader :source
|
656
|
+
include Serie.with(source: true)
|
701
657
|
|
702
658
|
def initialize(serie)
|
703
|
-
|
659
|
+
self.source = serie
|
660
|
+
init
|
661
|
+
end
|
704
662
|
|
663
|
+
private def _init
|
705
664
|
@restart_on_next = false
|
706
|
-
|
707
|
-
mark_regarding! @source
|
708
665
|
end
|
709
666
|
|
710
|
-
def _restart
|
667
|
+
private def _restart
|
711
668
|
@source.restart
|
712
669
|
end
|
713
670
|
|
714
|
-
def _next_value
|
671
|
+
private def _next_value
|
715
672
|
if @restart_on_next
|
716
673
|
@source.restart
|
717
674
|
@restart_on_next = false
|
@@ -728,53 +685,59 @@ module Musa
|
|
728
685
|
private_constant :Autorestart
|
729
686
|
|
730
687
|
class Cutter
|
731
|
-
include Serie
|
732
|
-
|
733
|
-
attr_reader :source, :length
|
688
|
+
include Serie.with(source: true)
|
734
689
|
|
735
690
|
def initialize(serie, length)
|
736
|
-
|
737
|
-
|
691
|
+
self.source = serie
|
692
|
+
self.length = length
|
693
|
+
init
|
694
|
+
end
|
738
695
|
|
739
|
-
|
696
|
+
def source=(serie)
|
697
|
+
super
|
698
|
+
@previous&.source = serie
|
740
699
|
end
|
741
700
|
|
742
|
-
|
743
|
-
|
701
|
+
attr_reader :length
|
702
|
+
|
703
|
+
def length=(value)
|
704
|
+
@length = value
|
705
|
+
@previous&.length = value
|
744
706
|
end
|
745
707
|
|
746
|
-
def
|
747
|
-
@
|
708
|
+
private def _restart
|
709
|
+
@source.restart
|
710
|
+
end
|
748
711
|
|
712
|
+
private def _next_value
|
713
|
+
@previous&.materialize
|
749
714
|
@previous = CutSerie.new @source, @length if @source.peek_next_value
|
750
715
|
end
|
751
716
|
|
752
|
-
private
|
753
|
-
|
754
717
|
class CutSerie
|
755
|
-
include Serie
|
718
|
+
include Serie.with(source: true)
|
756
719
|
|
757
720
|
def initialize(serie, length)
|
758
|
-
|
759
|
-
|
721
|
+
self.source = serie.instance
|
722
|
+
self.length = length
|
760
723
|
|
761
724
|
@values = []
|
762
|
-
|
763
|
-
|
764
|
-
mark_as_instance!
|
725
|
+
init
|
765
726
|
end
|
766
727
|
|
728
|
+
attr_accessor :length
|
729
|
+
|
767
730
|
def _prototype!
|
768
731
|
# TODO review why cannot get prototype of a cut serie
|
769
|
-
raise
|
732
|
+
raise PrototypingError, 'Cannot get prototype of a cut serie'
|
770
733
|
end
|
771
734
|
|
772
|
-
def
|
735
|
+
private def _init
|
773
736
|
@count = 0
|
774
737
|
end
|
775
738
|
|
776
|
-
def _next_value
|
777
|
-
value
|
739
|
+
private def _next_value
|
740
|
+
value = @values[@count]
|
778
741
|
value ||= @values[@count] = @source.next_value if @count < @length
|
779
742
|
|
780
743
|
@count += 1
|
@@ -786,30 +749,29 @@ module Musa
|
|
786
749
|
(@values.size..@length - 1).each { |i| @values[i] = @source.next_value }
|
787
750
|
end
|
788
751
|
end
|
752
|
+
|
753
|
+
private_constant :CutSerie
|
789
754
|
end
|
790
755
|
|
791
756
|
private_constant :Cutter
|
792
757
|
|
793
758
|
class Locker
|
794
|
-
include Serie
|
795
|
-
|
796
|
-
attr_reader :source
|
759
|
+
include Serie.with(source: true)
|
797
760
|
|
798
761
|
def initialize(serie)
|
799
|
-
|
762
|
+
self.source = serie
|
763
|
+
|
800
764
|
@values = []
|
801
765
|
@first_round = true
|
802
766
|
|
803
|
-
|
804
|
-
|
805
|
-
mark_regarding! @source
|
767
|
+
init
|
806
768
|
end
|
807
769
|
|
808
|
-
def
|
770
|
+
private def _init
|
809
771
|
@index = 0
|
810
772
|
end
|
811
773
|
|
812
|
-
def _next_value
|
774
|
+
private def _next_value
|
813
775
|
if @first_round
|
814
776
|
value = @source.next_value
|
815
777
|
|
@@ -831,34 +793,33 @@ module Musa
|
|
831
793
|
private_constant :Locker
|
832
794
|
|
833
795
|
class Reverser
|
834
|
-
include Serie
|
835
|
-
|
836
|
-
attr_reader :source
|
796
|
+
include Serie.with(source: true)
|
837
797
|
|
838
798
|
def initialize(serie)
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
mark_regarding! @source
|
799
|
+
self.source = serie
|
800
|
+
init
|
843
801
|
end
|
844
802
|
|
845
|
-
def
|
803
|
+
def source=(serie)
|
804
|
+
raise ArgumentError, "A serie to reverse can't be infinite" if serie.infinite?
|
846
805
|
super
|
847
|
-
|
806
|
+
init
|
848
807
|
end
|
849
808
|
|
850
|
-
def
|
851
|
-
@
|
852
|
-
@reversed = FromArray.new(next_values_array_of(@source).reverse).instance if get_reversed
|
809
|
+
private def _init
|
810
|
+
@reversed = nil
|
853
811
|
end
|
854
812
|
|
855
|
-
def
|
856
|
-
@
|
813
|
+
private def _restart
|
814
|
+
@source.restart
|
857
815
|
end
|
858
816
|
|
859
|
-
private
|
817
|
+
private def _next_value
|
818
|
+
@reversed ||= Constructors.S(*next_values_array_of(@source).reverse).instance
|
819
|
+
@reversed.next_value
|
820
|
+
end
|
860
821
|
|
861
|
-
def next_values_array_of(serie)
|
822
|
+
private def next_values_array_of(serie)
|
862
823
|
array = []
|
863
824
|
|
864
825
|
until (value = serie.next_value).nil?
|
@@ -872,25 +833,27 @@ module Musa
|
|
872
833
|
private_constant :Reverser
|
873
834
|
|
874
835
|
class Randomizer
|
875
|
-
include Serie
|
876
|
-
|
877
|
-
attr_reader :source, :random
|
836
|
+
include Serie.with(source: true)
|
878
837
|
|
879
838
|
def initialize(serie, random)
|
880
|
-
|
881
|
-
|
839
|
+
self.source = serie
|
840
|
+
self.random = random
|
882
841
|
|
883
|
-
|
842
|
+
init
|
843
|
+
end
|
884
844
|
|
885
|
-
|
845
|
+
attr_accessor :random
|
846
|
+
|
847
|
+
private def _init
|
848
|
+
@values = @source.to_a(duplicate: false, restart: false)
|
886
849
|
end
|
887
850
|
|
888
|
-
def _restart
|
889
|
-
@source.restart
|
890
|
-
@values = @source.to_a
|
851
|
+
private def _restart
|
852
|
+
@source.restart
|
853
|
+
@values = @source.to_a(duplicate: false, restart: false)
|
891
854
|
end
|
892
855
|
|
893
|
-
def _next_value
|
856
|
+
private def _next_value
|
894
857
|
if !@values.empty?
|
895
858
|
position = @random.rand(0...@values.size)
|
896
859
|
value = @values[position]
|
@@ -907,30 +870,46 @@ module Musa
|
|
907
870
|
private_constant :Randomizer
|
908
871
|
|
909
872
|
class Shifter
|
910
|
-
include Serie
|
911
|
-
|
912
|
-
attr_reader :source, :shift
|
873
|
+
include Serie.with(source: true)
|
913
874
|
|
914
875
|
def initialize(serie, shift)
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
@source = serie
|
919
|
-
@shift = shift
|
876
|
+
self.source = serie
|
877
|
+
self.shift = shift
|
920
878
|
|
921
|
-
|
879
|
+
init
|
880
|
+
end
|
922
881
|
|
923
|
-
|
882
|
+
def source=(serie)
|
883
|
+
raise ArgumentError, "cannot shift to right an infinite serie" if @shift > 0 && serie.infinite?
|
884
|
+
super
|
885
|
+
# should _restart(false) ??? if so, we lost the shifted values of the previous serie; if not we don't shift the new serie values
|
886
|
+
# I think it's better to not _restart unless it's explicitly called by the caller
|
924
887
|
end
|
925
888
|
|
926
|
-
|
927
|
-
|
889
|
+
attr_reader :shift
|
890
|
+
|
891
|
+
def shift=(value)
|
892
|
+
raise ArgumentError, "cannot shift to right an infinite serie" if value > 0 && @source&.infinite?
|
893
|
+
raise NotImplementedError, 'cannot shift to right: function not yet implemented' if value > 0
|
894
|
+
|
895
|
+
@shift = value
|
896
|
+
end
|
928
897
|
|
898
|
+
private def _init
|
929
899
|
@shifted = []
|
930
|
-
@
|
900
|
+
@first = true
|
931
901
|
end
|
932
902
|
|
933
|
-
def
|
903
|
+
private def _restart
|
904
|
+
@source.restart
|
905
|
+
end
|
906
|
+
|
907
|
+
private def _next_value
|
908
|
+
if @first
|
909
|
+
@shift.abs.times { @shifted << @source.next_value } if @shift < 0
|
910
|
+
@first = false
|
911
|
+
end
|
912
|
+
|
934
913
|
value = @source.next_value
|
935
914
|
return value unless value.nil?
|
936
915
|
|
@@ -941,28 +920,28 @@ module Musa
|
|
941
920
|
private_constant :Shifter
|
942
921
|
|
943
922
|
class Remover
|
944
|
-
include Serie
|
945
|
-
|
946
|
-
attr_reader :source
|
923
|
+
include Serie.with(source: true, block: true)
|
947
924
|
|
948
925
|
def initialize(serie, &block)
|
949
|
-
|
950
|
-
|
951
|
-
@history = []
|
926
|
+
self.source = serie
|
927
|
+
self.proc = block
|
952
928
|
|
953
|
-
|
929
|
+
@history = []
|
954
930
|
|
955
|
-
|
931
|
+
init
|
956
932
|
end
|
957
933
|
|
958
|
-
def
|
959
|
-
@source.restart if restart_sources
|
934
|
+
private def _init
|
960
935
|
@history.clear
|
961
936
|
end
|
962
937
|
|
963
|
-
def
|
938
|
+
private def _restart
|
939
|
+
@source.restart
|
940
|
+
end
|
941
|
+
|
942
|
+
private def _next_value
|
964
943
|
if value = @source.next_value
|
965
|
-
while @block.call(value, @history)
|
944
|
+
while value && @block.call(value, @history)
|
966
945
|
@history << value
|
967
946
|
value = @source.next_value
|
968
947
|
end
|
@@ -975,24 +954,20 @@ module Musa
|
|
975
954
|
private_constant :Remover
|
976
955
|
|
977
956
|
class Selector
|
978
|
-
include Serie
|
979
|
-
|
980
|
-
attr_reader :source
|
957
|
+
include Serie.with(source: true, block: true)
|
981
958
|
|
982
959
|
def initialize(serie, &block)
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
_restart false
|
960
|
+
self.source = serie
|
961
|
+
self.proc = block
|
987
962
|
|
988
|
-
|
963
|
+
init
|
989
964
|
end
|
990
965
|
|
991
|
-
def _restart
|
992
|
-
@source.restart
|
966
|
+
private def _restart
|
967
|
+
@source.restart
|
993
968
|
end
|
994
969
|
|
995
|
-
def _next_value
|
970
|
+
private def _next_value
|
996
971
|
value = @source.next_value
|
997
972
|
until value.nil? || @block.call(value)
|
998
973
|
value = @source.next_value
|
@@ -1004,23 +979,22 @@ module Musa
|
|
1004
979
|
private_constant :Selector
|
1005
980
|
|
1006
981
|
class HashFromSeriesArray
|
1007
|
-
include Serie
|
1008
|
-
|
1009
|
-
attr_reader :source, :keys
|
982
|
+
include Serie.with(source: true)
|
1010
983
|
|
1011
984
|
def initialize(serie, keys)
|
1012
|
-
|
1013
|
-
|
1014
|
-
_restart false
|
985
|
+
self.source = serie
|
986
|
+
self.keys = keys
|
1015
987
|
|
1016
|
-
|
988
|
+
init
|
1017
989
|
end
|
1018
990
|
|
1019
|
-
|
1020
|
-
|
991
|
+
attr_accessor :keys
|
992
|
+
|
993
|
+
private def _restart
|
994
|
+
@source.restart
|
1021
995
|
end
|
1022
996
|
|
1023
|
-
def _next_value
|
997
|
+
private def _next_value
|
1024
998
|
array = @source.next_value
|
1025
999
|
|
1026
1000
|
return nil unless array
|
@@ -1036,6 +1010,45 @@ module Musa
|
|
1036
1010
|
end
|
1037
1011
|
|
1038
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
|
1039
1051
|
end
|
1052
|
+
|
1040
1053
|
end
|
1041
1054
|
end
|