musa-dsl 0.22.6 → 0.23.4
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/smart-proc-binder.rb +13 -11
- data/lib/musa-dsl/datasets/p.rb +14 -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/midi/midi-voices.rb +7 -7
- 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/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 +142 -128
- data/lib/musa-dsl/series/main-serie-constructors.rb +248 -155
- data/lib/musa-dsl/series/main-serie-operations.rb +324 -316
- 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 +106 -119
- data/musa-dsl.gemspec +12 -2
- metadata +7 -7
- 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,23 +179,20 @@ 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
|
193
196
|
previous_value = @source.current_value
|
194
197
|
value = @source.next_value
|
195
198
|
peek_next_value = @source.peek_next_value
|
@@ -209,30 +212,16 @@ module Musa
|
|
209
212
|
private_constant :Anticipate
|
210
213
|
|
211
214
|
class Switcher
|
212
|
-
include Serie
|
213
|
-
|
214
|
-
attr_accessor :sources
|
215
|
-
def selector; @source; end
|
215
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
216
216
|
|
217
217
|
def initialize(selector, indexed_series, hash_series)
|
218
|
+
self.source = selector
|
219
|
+
self.options = indexed_series || hash_series
|
218
220
|
|
219
|
-
|
220
|
-
get = @source.prototype? ? :prototype : :instance
|
221
|
-
|
222
|
-
if indexed_series && !indexed_series.empty?
|
223
|
-
@sources = indexed_series.collect(&get)
|
224
|
-
elsif hash_series && !hash_series.empty?
|
225
|
-
@sources = hash_series.clone.transform_values(&get)
|
226
|
-
end
|
227
|
-
|
228
|
-
if get == :prototype!
|
229
|
-
@sources.freeze
|
230
|
-
end
|
231
|
-
|
232
|
-
mark_regarding! @source
|
221
|
+
init
|
233
222
|
end
|
234
223
|
|
235
|
-
def _restart
|
224
|
+
private def _restart
|
236
225
|
@source.restart
|
237
226
|
if @sources.is_a? Array
|
238
227
|
@sources.each(&:restart)
|
@@ -241,7 +230,7 @@ module Musa
|
|
241
230
|
end
|
242
231
|
end
|
243
232
|
|
244
|
-
def _next_value
|
233
|
+
private def _next_value
|
245
234
|
value = nil
|
246
235
|
|
247
236
|
index_or_key = @source.next_value
|
@@ -259,46 +248,31 @@ module Musa
|
|
259
248
|
private_constant :Switcher
|
260
249
|
|
261
250
|
class MultiplexSelector
|
262
|
-
include Serie
|
263
|
-
|
264
|
-
def selector; @source; end
|
265
|
-
attr_accessor :sources
|
251
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
266
252
|
|
267
253
|
def initialize(selector, indexed_series, hash_series)
|
268
|
-
|
269
|
-
|
254
|
+
self.source = selector
|
255
|
+
self.options = indexed_series || hash_series
|
270
256
|
|
271
|
-
|
272
|
-
@sources = indexed_series.collect(&get)
|
273
|
-
elsif hash_series && !hash_series.empty?
|
274
|
-
@sources = hash_series.clone.transform_values(&get)
|
275
|
-
end
|
276
|
-
|
277
|
-
_restart false
|
278
|
-
|
279
|
-
if get == :prototype
|
280
|
-
@sources.freeze
|
281
|
-
end
|
282
|
-
|
283
|
-
mark_regarding! @source
|
257
|
+
init
|
284
258
|
end
|
285
259
|
|
286
|
-
def
|
260
|
+
private def _init
|
287
261
|
@current_value = nil
|
262
|
+
@first = true
|
263
|
+
end
|
288
264
|
|
289
|
-
|
290
|
-
|
291
|
-
if @sources.is_a? Array
|
292
|
-
@sources.each(&:restart)
|
293
|
-
elsif @sources.is_a? Hash
|
294
|
-
@sources.each { |_key, serie| serie.restart }
|
295
|
-
end
|
296
|
-
end
|
265
|
+
private def _restart
|
266
|
+
@source.restart
|
297
267
|
|
298
|
-
@
|
268
|
+
if @sources.is_a? Array
|
269
|
+
@sources.each(&:restart)
|
270
|
+
elsif @sources.is_a? Hash
|
271
|
+
@sources.values.each(&:restart)
|
272
|
+
end
|
299
273
|
end
|
300
274
|
|
301
|
-
def _next_value
|
275
|
+
private def _next_value
|
302
276
|
@current_value =
|
303
277
|
if @first || !@current_value.nil?
|
304
278
|
@first = false
|
@@ -318,34 +292,21 @@ module Musa
|
|
318
292
|
private_constant :MultiplexSelector
|
319
293
|
|
320
294
|
class SwitchFullSerie
|
321
|
-
include Serie
|
322
|
-
|
323
|
-
def selector; @source; end
|
324
|
-
attr_accessor :sources
|
295
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
325
296
|
|
326
297
|
def initialize(selector, indexed_series, hash_series)
|
327
|
-
|
328
|
-
|
298
|
+
self.source = selector
|
299
|
+
self.options = indexed_series || hash_series
|
329
300
|
|
330
|
-
|
331
|
-
@sources = indexed_series.collect(&get)
|
332
|
-
elsif hash_series && !hash_series.empty?
|
333
|
-
@sources = hash_series.clone.transform_values(&get)
|
334
|
-
end
|
335
|
-
|
336
|
-
if get == :prototype
|
337
|
-
@sources.freeze
|
338
|
-
end
|
339
|
-
|
340
|
-
mark_regarding! @source
|
301
|
+
init
|
341
302
|
end
|
342
303
|
|
343
|
-
def _restart
|
304
|
+
private def _restart
|
344
305
|
@source.restart
|
345
306
|
@sources.each(&:restart)
|
346
307
|
end
|
347
308
|
|
348
|
-
def _next_value
|
309
|
+
private def _next_value
|
349
310
|
value = nil
|
350
311
|
|
351
312
|
value = @sources[@index_or_key].next_value unless @index_or_key.nil?
|
@@ -367,21 +328,18 @@ module Musa
|
|
367
328
|
private_constant :SwitchFullSerie
|
368
329
|
|
369
330
|
class InfiniteRepeater
|
370
|
-
include Serie
|
371
|
-
|
372
|
-
attr_reader :source
|
331
|
+
include Serie.with(source: true)
|
373
332
|
|
374
333
|
def initialize(serie)
|
375
|
-
|
376
|
-
|
377
|
-
mark_regarding! @source
|
334
|
+
self.source = serie
|
335
|
+
init
|
378
336
|
end
|
379
337
|
|
380
|
-
def _restart
|
338
|
+
private def _restart
|
381
339
|
@source.restart
|
382
340
|
end
|
383
341
|
|
384
|
-
def _next_value
|
342
|
+
private def _next_value
|
385
343
|
value = @source.next_value
|
386
344
|
|
387
345
|
if value.nil?
|
@@ -400,38 +358,47 @@ module Musa
|
|
400
358
|
private_constant :InfiniteRepeater
|
401
359
|
|
402
360
|
class Repeater
|
403
|
-
include Serie
|
404
|
-
|
405
|
-
attr_reader :source, :times, :condition
|
361
|
+
include Serie.with(source: true)
|
406
362
|
|
407
363
|
def initialize(serie, times = nil, &condition)
|
408
|
-
|
364
|
+
self.source = serie
|
365
|
+
self.times = times
|
366
|
+
self.condition = condition
|
409
367
|
|
410
|
-
|
411
|
-
|
368
|
+
init
|
369
|
+
end
|
412
370
|
|
413
|
-
|
414
|
-
@condition = calculate_condition
|
371
|
+
attr_reader :times
|
415
372
|
|
416
|
-
|
373
|
+
def times=(value)
|
374
|
+
@times = value
|
375
|
+
calculate_condition
|
417
376
|
end
|
418
377
|
|
419
|
-
def
|
420
|
-
|
421
|
-
|
378
|
+
def condition(&block)
|
379
|
+
if block
|
380
|
+
@external_condition = block
|
381
|
+
calculate_condition
|
382
|
+
else
|
383
|
+
@external_condition
|
384
|
+
end
|
422
385
|
end
|
423
386
|
|
424
|
-
def
|
425
|
-
|
426
|
-
|
387
|
+
def condition=(block)
|
388
|
+
@external_condition = block
|
389
|
+
calculate_condition
|
427
390
|
end
|
428
391
|
|
429
|
-
def
|
392
|
+
private def _init
|
430
393
|
@count = 0
|
431
|
-
|
394
|
+
calculate_condition
|
432
395
|
end
|
433
396
|
|
434
|
-
def
|
397
|
+
private def _restart
|
398
|
+
@source.restart
|
399
|
+
end
|
400
|
+
|
401
|
+
private def _next_value
|
435
402
|
value = @source.next_value
|
436
403
|
|
437
404
|
if value.nil?
|
@@ -451,38 +418,39 @@ module Musa
|
|
451
418
|
end
|
452
419
|
|
453
420
|
private def calculate_condition
|
454
|
-
if @external_condition
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
421
|
+
@condition = if @external_condition
|
422
|
+
@external_condition
|
423
|
+
elsif @times
|
424
|
+
proc { @count < @times }
|
425
|
+
else
|
426
|
+
proc { false }
|
427
|
+
end
|
461
428
|
end
|
462
429
|
end
|
463
430
|
|
464
431
|
private_constant :Repeater
|
465
432
|
|
466
433
|
class LengthLimiter
|
467
|
-
include Serie
|
468
|
-
|
469
|
-
attr_reader :source, :length
|
434
|
+
include Serie.with(source: true)
|
470
435
|
|
471
436
|
def initialize(serie, length)
|
472
|
-
|
473
|
-
|
437
|
+
self.source = serie
|
438
|
+
self.length = length
|
474
439
|
|
475
|
-
|
476
|
-
|
477
|
-
mark_regarding! @source
|
440
|
+
init
|
478
441
|
end
|
479
442
|
|
480
|
-
|
443
|
+
attr_accessor :length
|
444
|
+
|
445
|
+
private def _init
|
481
446
|
@position = 0
|
482
|
-
@source.restart if restart_sources
|
483
447
|
end
|
484
448
|
|
485
|
-
def
|
449
|
+
private def _restart
|
450
|
+
@source.restart
|
451
|
+
end
|
452
|
+
|
453
|
+
private def _next_value
|
486
454
|
if @position < @length
|
487
455
|
@position += 1
|
488
456
|
@source.next_value
|
@@ -497,25 +465,26 @@ module Musa
|
|
497
465
|
private_constant :LengthLimiter
|
498
466
|
|
499
467
|
class Skipper
|
500
|
-
include Serie
|
501
|
-
|
502
|
-
attr_reader :source, :length
|
468
|
+
include Serie.with(source: true)
|
503
469
|
|
504
470
|
def initialize(serie, length)
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
_restart false
|
471
|
+
self.source = serie
|
472
|
+
self.length = length
|
509
473
|
|
510
|
-
|
474
|
+
init
|
511
475
|
end
|
512
476
|
|
513
|
-
|
514
|
-
|
477
|
+
attr_accessor :length
|
478
|
+
|
479
|
+
private def _init
|
515
480
|
@first = true
|
516
481
|
end
|
517
482
|
|
518
|
-
def
|
483
|
+
private def _restart
|
484
|
+
@source.restart
|
485
|
+
end
|
486
|
+
|
487
|
+
private def _next_value
|
519
488
|
@length.times { @source.next_value } if @first
|
520
489
|
@first = nil
|
521
490
|
|
@@ -530,40 +499,25 @@ module Musa
|
|
530
499
|
private_constant :Skipper
|
531
500
|
|
532
501
|
class Flattener
|
533
|
-
include Serie
|
534
|
-
|
535
|
-
attr_reader :source
|
502
|
+
include Serie.base
|
536
503
|
|
537
504
|
def initialize(serie)
|
538
505
|
@source = serie
|
539
|
-
|
540
|
-
_restart false
|
541
|
-
|
542
506
|
mark_regarding! @source
|
507
|
+
init
|
543
508
|
end
|
544
509
|
|
545
|
-
def
|
546
|
-
|
547
|
-
|
548
|
-
end
|
549
|
-
|
550
|
-
def _instance!
|
551
|
-
super
|
552
|
-
_restart false
|
510
|
+
private def _init
|
511
|
+
@stack = [@source]
|
512
|
+
@restart_each_serie = false
|
553
513
|
end
|
554
514
|
|
555
|
-
def _restart
|
556
|
-
|
557
|
-
|
558
|
-
@restart_each_serie = true
|
559
|
-
else
|
560
|
-
@restart_each_serie = false
|
561
|
-
end
|
562
|
-
|
563
|
-
@stack = [@source]
|
515
|
+
private def _restart
|
516
|
+
@source.restart
|
517
|
+
@restart_each_serie = true
|
564
518
|
end
|
565
519
|
|
566
|
-
def _next_value
|
520
|
+
private def _next_value
|
567
521
|
if @stack.last
|
568
522
|
value = @stack.last.next_value
|
569
523
|
|
@@ -590,26 +544,24 @@ module Musa
|
|
590
544
|
private_constant :Flattener
|
591
545
|
|
592
546
|
class MergeSerieOfSeries
|
593
|
-
include Serie
|
594
|
-
|
595
|
-
attr_reader :source
|
547
|
+
include Serie.with(source: true)
|
596
548
|
|
597
549
|
def initialize(serie)
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
mark_regarding! @source
|
550
|
+
self.source = serie
|
551
|
+
init
|
602
552
|
end
|
603
553
|
|
604
|
-
def
|
605
|
-
if restart_sources
|
606
|
-
@source.restart
|
607
|
-
@restart_each_serie = true
|
608
|
-
end
|
554
|
+
private def _init
|
609
555
|
@current_serie = nil
|
556
|
+
@restart_each_serie = false
|
557
|
+
end
|
558
|
+
|
559
|
+
private def _restart
|
560
|
+
@source.restart
|
561
|
+
@restart_each_serie = true
|
610
562
|
end
|
611
563
|
|
612
|
-
def _next_value
|
564
|
+
private def _next_value
|
613
565
|
value = nil
|
614
566
|
|
615
567
|
restart_current_serie_if_needed = false
|
@@ -646,27 +598,28 @@ module Musa
|
|
646
598
|
private_constant :MergeSerieOfSeries
|
647
599
|
|
648
600
|
class Processor
|
649
|
-
include
|
650
|
-
include Serie
|
651
|
-
|
652
|
-
attr_reader :source
|
601
|
+
include Serie.with(source: true, smart_block: true)
|
653
602
|
|
654
603
|
def initialize(serie, parameters, &processor)
|
655
|
-
|
656
|
-
@parameters = parameters
|
657
|
-
@processor = SmartProcBinder.new(processor)
|
604
|
+
self.source = serie
|
658
605
|
|
659
|
-
|
606
|
+
self.parameters = parameters
|
607
|
+
self.proc = processor if processor
|
660
608
|
|
661
|
-
|
609
|
+
init
|
662
610
|
end
|
663
611
|
|
664
|
-
|
665
|
-
|
612
|
+
attr_accessor :parameters
|
613
|
+
|
614
|
+
private def _init
|
666
615
|
@pending_values = []
|
667
616
|
end
|
668
617
|
|
669
|
-
def
|
618
|
+
private def _restart
|
619
|
+
@source.restart
|
620
|
+
end
|
621
|
+
|
622
|
+
private def _next_value
|
670
623
|
if @pending_values.empty?
|
671
624
|
|
672
625
|
v = @source.next_value
|
@@ -674,7 +627,7 @@ module Musa
|
|
674
627
|
if v.nil?
|
675
628
|
nil
|
676
629
|
else
|
677
|
-
value = @
|
630
|
+
value = @block.call(v, **@parameters)
|
678
631
|
|
679
632
|
if value.is_a?(Array)
|
680
633
|
@pending_values = value
|
@@ -700,23 +653,22 @@ module Musa
|
|
700
653
|
end
|
701
654
|
|
702
655
|
class Autorestart
|
703
|
-
include Serie
|
704
|
-
|
705
|
-
attr_reader :source
|
656
|
+
include Serie.with(source: true)
|
706
657
|
|
707
658
|
def initialize(serie)
|
708
|
-
|
659
|
+
self.source = serie
|
660
|
+
init
|
661
|
+
end
|
709
662
|
|
663
|
+
private def _init
|
710
664
|
@restart_on_next = false
|
711
|
-
|
712
|
-
mark_regarding! @source
|
713
665
|
end
|
714
666
|
|
715
|
-
def _restart
|
667
|
+
private def _restart
|
716
668
|
@source.restart
|
717
669
|
end
|
718
670
|
|
719
|
-
def _next_value
|
671
|
+
private def _next_value
|
720
672
|
if @restart_on_next
|
721
673
|
@source.restart
|
722
674
|
@restart_on_next = false
|
@@ -733,53 +685,59 @@ module Musa
|
|
733
685
|
private_constant :Autorestart
|
734
686
|
|
735
687
|
class Cutter
|
736
|
-
include Serie
|
737
|
-
|
738
|
-
attr_reader :source, :length
|
688
|
+
include Serie.with(source: true)
|
739
689
|
|
740
690
|
def initialize(serie, length)
|
741
|
-
|
742
|
-
|
691
|
+
self.source = serie
|
692
|
+
self.length = length
|
693
|
+
init
|
694
|
+
end
|
743
695
|
|
744
|
-
|
696
|
+
def source=(serie)
|
697
|
+
super
|
698
|
+
@previous&.source = serie
|
745
699
|
end
|
746
700
|
|
747
|
-
|
748
|
-
|
701
|
+
attr_reader :length
|
702
|
+
|
703
|
+
def length=(value)
|
704
|
+
@length = value
|
705
|
+
@previous&.length = value
|
749
706
|
end
|
750
707
|
|
751
|
-
def
|
752
|
-
@
|
708
|
+
private def _restart
|
709
|
+
@source.restart
|
710
|
+
end
|
753
711
|
|
712
|
+
private def _next_value
|
713
|
+
@previous&.materialize
|
754
714
|
@previous = CutSerie.new @source, @length if @source.peek_next_value
|
755
715
|
end
|
756
716
|
|
757
|
-
private
|
758
|
-
|
759
717
|
class CutSerie
|
760
|
-
include Serie
|
718
|
+
include Serie.with(source: true)
|
761
719
|
|
762
720
|
def initialize(serie, length)
|
763
|
-
|
764
|
-
|
721
|
+
self.source = serie.instance
|
722
|
+
self.length = length
|
765
723
|
|
766
724
|
@values = []
|
767
|
-
|
768
|
-
|
769
|
-
mark_as_instance!
|
725
|
+
init
|
770
726
|
end
|
771
727
|
|
728
|
+
attr_accessor :length
|
729
|
+
|
772
730
|
def _prototype!
|
773
731
|
# TODO review why cannot get prototype of a cut serie
|
774
|
-
raise
|
732
|
+
raise PrototypingError, 'Cannot get prototype of a cut serie'
|
775
733
|
end
|
776
734
|
|
777
|
-
def
|
735
|
+
private def _init
|
778
736
|
@count = 0
|
779
737
|
end
|
780
738
|
|
781
|
-
def _next_value
|
782
|
-
value
|
739
|
+
private def _next_value
|
740
|
+
value = @values[@count]
|
783
741
|
value ||= @values[@count] = @source.next_value if @count < @length
|
784
742
|
|
785
743
|
@count += 1
|
@@ -791,30 +749,29 @@ module Musa
|
|
791
749
|
(@values.size..@length - 1).each { |i| @values[i] = @source.next_value }
|
792
750
|
end
|
793
751
|
end
|
752
|
+
|
753
|
+
private_constant :CutSerie
|
794
754
|
end
|
795
755
|
|
796
756
|
private_constant :Cutter
|
797
757
|
|
798
758
|
class Locker
|
799
|
-
include Serie
|
800
|
-
|
801
|
-
attr_reader :source
|
759
|
+
include Serie.with(source: true)
|
802
760
|
|
803
761
|
def initialize(serie)
|
804
|
-
|
762
|
+
self.source = serie
|
763
|
+
|
805
764
|
@values = []
|
806
765
|
@first_round = true
|
807
766
|
|
808
|
-
|
809
|
-
|
810
|
-
mark_regarding! @source
|
767
|
+
init
|
811
768
|
end
|
812
769
|
|
813
|
-
def
|
770
|
+
private def _init
|
814
771
|
@index = 0
|
815
772
|
end
|
816
773
|
|
817
|
-
def _next_value
|
774
|
+
private def _next_value
|
818
775
|
if @first_round
|
819
776
|
value = @source.next_value
|
820
777
|
|
@@ -836,34 +793,33 @@ module Musa
|
|
836
793
|
private_constant :Locker
|
837
794
|
|
838
795
|
class Reverser
|
839
|
-
include Serie
|
840
|
-
|
841
|
-
attr_reader :source
|
796
|
+
include Serie.with(source: true)
|
842
797
|
|
843
798
|
def initialize(serie)
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
mark_regarding! @source
|
799
|
+
self.source = serie
|
800
|
+
init
|
848
801
|
end
|
849
802
|
|
850
|
-
def
|
803
|
+
def source=(serie)
|
804
|
+
raise ArgumentError, "A serie to reverse can't be infinite" if serie.infinite?
|
851
805
|
super
|
852
|
-
|
806
|
+
init
|
853
807
|
end
|
854
808
|
|
855
|
-
def
|
856
|
-
@
|
857
|
-
@reversed = FromArray.new(next_values_array_of(@source).reverse).instance if get_reversed
|
809
|
+
private def _init
|
810
|
+
@reversed = nil
|
858
811
|
end
|
859
812
|
|
860
|
-
def
|
861
|
-
@
|
813
|
+
private def _restart
|
814
|
+
@source.restart
|
862
815
|
end
|
863
816
|
|
864
|
-
private
|
817
|
+
private def _next_value
|
818
|
+
@reversed ||= Constructors.S(*next_values_array_of(@source).reverse).instance
|
819
|
+
@reversed.next_value
|
820
|
+
end
|
865
821
|
|
866
|
-
def next_values_array_of(serie)
|
822
|
+
private def next_values_array_of(serie)
|
867
823
|
array = []
|
868
824
|
|
869
825
|
until (value = serie.next_value).nil?
|
@@ -877,25 +833,27 @@ module Musa
|
|
877
833
|
private_constant :Reverser
|
878
834
|
|
879
835
|
class Randomizer
|
880
|
-
include Serie
|
881
|
-
|
882
|
-
attr_reader :source, :random
|
836
|
+
include Serie.with(source: true)
|
883
837
|
|
884
838
|
def initialize(serie, random)
|
885
|
-
|
886
|
-
|
839
|
+
self.source = serie
|
840
|
+
self.random = random
|
841
|
+
|
842
|
+
init
|
843
|
+
end
|
887
844
|
|
888
|
-
|
845
|
+
attr_accessor :random
|
889
846
|
|
890
|
-
|
847
|
+
private def _init
|
848
|
+
@values = @source.to_a(duplicate: false, restart: false)
|
891
849
|
end
|
892
850
|
|
893
|
-
def _restart
|
894
|
-
@source.restart
|
895
|
-
@values = @source.to_a
|
851
|
+
private def _restart
|
852
|
+
@source.restart
|
853
|
+
@values = @source.to_a(duplicate: false, restart: false)
|
896
854
|
end
|
897
855
|
|
898
|
-
def _next_value
|
856
|
+
private def _next_value
|
899
857
|
if !@values.empty?
|
900
858
|
position = @random.rand(0...@values.size)
|
901
859
|
value = @values[position]
|
@@ -912,30 +870,46 @@ module Musa
|
|
912
870
|
private_constant :Randomizer
|
913
871
|
|
914
872
|
class Shifter
|
915
|
-
include Serie
|
916
|
-
|
917
|
-
attr_reader :source, :shift
|
873
|
+
include Serie.with(source: true)
|
918
874
|
|
919
875
|
def initialize(serie, shift)
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
@source = serie
|
924
|
-
@shift = shift
|
876
|
+
self.source = serie
|
877
|
+
self.shift = shift
|
925
878
|
|
926
|
-
|
879
|
+
init
|
880
|
+
end
|
927
881
|
|
928
|
-
|
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
|
929
887
|
end
|
930
888
|
|
931
|
-
|
932
|
-
@source.restart if restart_sources
|
889
|
+
attr_reader :shift
|
933
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
|
897
|
+
|
898
|
+
private def _init
|
934
899
|
@shifted = []
|
935
|
-
@
|
900
|
+
@first = true
|
901
|
+
end
|
902
|
+
|
903
|
+
private def _restart
|
904
|
+
@source.restart
|
936
905
|
end
|
937
906
|
|
938
|
-
def _next_value
|
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
|
+
|
939
913
|
value = @source.next_value
|
940
914
|
return value unless value.nil?
|
941
915
|
|
@@ -946,26 +920,26 @@ module Musa
|
|
946
920
|
private_constant :Shifter
|
947
921
|
|
948
922
|
class Remover
|
949
|
-
include Serie
|
950
|
-
|
951
|
-
attr_reader :source
|
923
|
+
include Serie.with(source: true, block: true)
|
952
924
|
|
953
925
|
def initialize(serie, &block)
|
954
|
-
|
955
|
-
|
956
|
-
@history = []
|
926
|
+
self.source = serie
|
927
|
+
self.proc = block
|
957
928
|
|
958
|
-
|
929
|
+
@history = []
|
959
930
|
|
960
|
-
|
931
|
+
init
|
961
932
|
end
|
962
933
|
|
963
|
-
def
|
964
|
-
@source.restart if restart_sources
|
934
|
+
private def _init
|
965
935
|
@history.clear
|
966
936
|
end
|
967
937
|
|
968
|
-
def
|
938
|
+
private def _restart
|
939
|
+
@source.restart
|
940
|
+
end
|
941
|
+
|
942
|
+
private def _next_value
|
969
943
|
if value = @source.next_value
|
970
944
|
while value && @block.call(value, @history)
|
971
945
|
@history << value
|
@@ -980,24 +954,20 @@ module Musa
|
|
980
954
|
private_constant :Remover
|
981
955
|
|
982
956
|
class Selector
|
983
|
-
include Serie
|
984
|
-
|
985
|
-
attr_reader :source
|
957
|
+
include Serie.with(source: true, block: true)
|
986
958
|
|
987
959
|
def initialize(serie, &block)
|
988
|
-
|
989
|
-
|
960
|
+
self.source = serie
|
961
|
+
self.proc = block
|
990
962
|
|
991
|
-
|
992
|
-
|
993
|
-
mark_regarding! @source
|
963
|
+
init
|
994
964
|
end
|
995
965
|
|
996
|
-
def _restart
|
997
|
-
@source.restart
|
966
|
+
private def _restart
|
967
|
+
@source.restart
|
998
968
|
end
|
999
969
|
|
1000
|
-
def _next_value
|
970
|
+
private def _next_value
|
1001
971
|
value = @source.next_value
|
1002
972
|
until value.nil? || @block.call(value)
|
1003
973
|
value = @source.next_value
|
@@ -1009,23 +979,22 @@ module Musa
|
|
1009
979
|
private_constant :Selector
|
1010
980
|
|
1011
981
|
class HashFromSeriesArray
|
1012
|
-
include Serie
|
1013
|
-
|
1014
|
-
attr_reader :source, :keys
|
982
|
+
include Serie.with(source: true)
|
1015
983
|
|
1016
984
|
def initialize(serie, keys)
|
1017
|
-
|
1018
|
-
|
1019
|
-
_restart false
|
985
|
+
self.source = serie
|
986
|
+
self.keys = keys
|
1020
987
|
|
1021
|
-
|
988
|
+
init
|
1022
989
|
end
|
1023
990
|
|
1024
|
-
|
1025
|
-
|
991
|
+
attr_accessor :keys
|
992
|
+
|
993
|
+
private def _restart
|
994
|
+
@source.restart
|
1026
995
|
end
|
1027
996
|
|
1028
|
-
def _next_value
|
997
|
+
private def _next_value
|
1029
998
|
array = @source.next_value
|
1030
999
|
|
1031
1000
|
return nil unless array
|
@@ -1041,6 +1010,45 @@ module Musa
|
|
1041
1010
|
end
|
1042
1011
|
|
1043
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
|
1044
1051
|
end
|
1052
|
+
|
1045
1053
|
end
|
1046
1054
|
end
|