musa-dsl 0.41.0 → 0.42.0
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/.gitignore +1 -0
- data/README.md +15 -1
- data/docs/README.md +1 -0
- data/docs/subsystems/datasets.md +75 -0
- data/docs/subsystems/generative.md +92 -6
- data/docs/subsystems/music.md +33 -14
- data/docs/subsystems/transport.md +26 -0
- data/lib/musa-dsl/datasets/dataset.rb +2 -0
- data/lib/musa-dsl/datasets/gdv.rb +3 -3
- data/lib/musa-dsl/datasets/p.rb +1 -1
- data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +4 -2
- data/lib/musa-dsl/datasets/score.rb +3 -1
- data/lib/musa-dsl/generative/generative-grammar.rb +3 -1
- data/lib/musa-dsl/generative/markov.rb +1 -1
- data/lib/musa-dsl/midi/midi-voices.rb +3 -1
- data/lib/musa-dsl/music/chord-definition.rb +7 -5
- data/lib/musa-dsl/music/chord-definitions.rb +37 -0
- data/lib/musa-dsl/music/chords.rb +69 -47
- data/lib/musa-dsl/music/scale_kinds/major_scale_kind.rb +1 -1
- data/lib/musa-dsl/music/scale_kinds/minor_natural_scale_kind.rb +1 -1
- data/lib/musa-dsl/music/scales.rb +219 -107
- data/lib/musa-dsl/musicxml/builder/note.rb +31 -92
- data/lib/musa-dsl/musicxml/builder/pitched-note.rb +33 -94
- data/lib/musa-dsl/musicxml/builder/rest.rb +30 -91
- data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +31 -91
- data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
- data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +2 -2
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +367 -3
- data/lib/musa-dsl/series/base-series.rb +250 -240
- data/lib/musa-dsl/series/buffer-serie.rb +10 -5
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +6 -3
- data/lib/musa-dsl/series/main-serie-constructors.rb +19 -15
- data/lib/musa-dsl/series/main-serie-operations.rb +74 -29
- data/lib/musa-dsl/series/proxy-serie.rb +5 -1
- data/lib/musa-dsl/series/quantizer-serie.rb +4 -2
- data/lib/musa-dsl/series/queue-serie.rb +2 -1
- data/lib/musa-dsl/series/series-composer.rb +5 -2
- data/lib/musa-dsl/series/timed-serie.rb +8 -4
- data/lib/musa-dsl/transport/timer-clock.rb +4 -2
- data/lib/musa-dsl/transport/timer.rb +27 -4
- data/lib/musa-dsl/version.rb +1 -2
- data/musa-dsl.gemspec +0 -2
- metadata +1 -1
|
@@ -187,251 +187,55 @@ module Musa
|
|
|
187
187
|
|
|
188
188
|
include Constructors
|
|
189
189
|
|
|
190
|
-
# Serie
|
|
190
|
+
# Serie mixins for building serie implementations.
|
|
191
191
|
#
|
|
192
|
-
#
|
|
192
|
+
# Provides composable modules for serie classes:
|
|
193
193
|
#
|
|
194
|
-
# -
|
|
195
|
-
# -
|
|
194
|
+
# - {Base} - Core functionality without dependencies
|
|
195
|
+
# - {WithSource} - Single upstream serie dependency
|
|
196
|
+
# - {WithSources} - Multiple upstream serie dependencies
|
|
197
|
+
# - {WithBlock} - Simple proc storage
|
|
198
|
+
# - {WithSmartBlock} - SmartProcBinder-wrapped proc
|
|
196
199
|
#
|
|
197
|
-
# ##
|
|
198
|
-
#
|
|
199
|
-
# Serie.with generates modules at runtime with specific features:
|
|
200
|
+
# ## Usage Pattern
|
|
200
201
|
#
|
|
201
202
|
# ```ruby
|
|
202
|
-
#
|
|
203
|
-
#
|
|
203
|
+
# class MySerie
|
|
204
|
+
# include Serie::Base
|
|
205
|
+
# include Serie::WithSource
|
|
204
206
|
#
|
|
205
|
-
#
|
|
206
|
-
#
|
|
207
|
+
# def initialize(source)
|
|
208
|
+
# self.source = source
|
|
209
|
+
# init
|
|
210
|
+
# mark_as_prototype!
|
|
211
|
+
# end
|
|
207
212
|
#
|
|
208
|
-
#
|
|
213
|
+
# private def _next_value
|
|
214
|
+
# @source.next_value&.transform
|
|
215
|
+
# end
|
|
216
|
+
# end
|
|
217
|
+
# ```
|
|
209
218
|
#
|
|
210
|
-
#
|
|
211
|
-
# - **sources**: Multiple upstream serie dependencies
|
|
212
|
-
# - **block**: Block/proc attribute
|
|
213
|
-
# - **smart_block**: SmartProcBinder-wrapped block
|
|
219
|
+
# ## Custom Accessor Names
|
|
214
220
|
#
|
|
215
|
-
#
|
|
221
|
+
# Use `alias` to create custom accessor names:
|
|
216
222
|
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
223
|
+
# ```ruby
|
|
224
|
+
# class MySerie
|
|
225
|
+
# include Serie::Base
|
|
226
|
+
# include Serie::WithSource
|
|
227
|
+
# alias upstream source
|
|
228
|
+
# alias upstream= source=
|
|
229
|
+
# end
|
|
230
|
+
# ```
|
|
219
231
|
#
|
|
220
|
-
# @see
|
|
232
|
+
# @see Base Core serie module
|
|
233
|
+
# @see WithSource Single source dependency
|
|
234
|
+
# @see WithSources Multiple sources dependency
|
|
235
|
+
# @see WithBlock Simple proc storage
|
|
236
|
+
# @see WithSmartBlock SmartProcBinder-wrapped proc
|
|
221
237
|
# @see Prototyping Prototype/instance state management
|
|
222
|
-
#
|
|
223
|
-
# @api private
|
|
224
238
|
module Serie
|
|
225
|
-
# Creates base serie module without dependencies.
|
|
226
|
-
#
|
|
227
|
-
# Minimal module for series that generate values without upstream
|
|
228
|
-
# sources (e.g., array-backed series, value generators).
|
|
229
|
-
#
|
|
230
|
-
# @return [Module] base module with SerieImplementation
|
|
231
|
-
#
|
|
232
|
-
# @example Base serie
|
|
233
|
-
# class SimpleSerie
|
|
234
|
-
# include Serie.base
|
|
235
|
-
#
|
|
236
|
-
# def _next_value
|
|
237
|
-
# # Generate value
|
|
238
|
-
# end
|
|
239
|
-
# end
|
|
240
|
-
#
|
|
241
|
-
# @api private
|
|
242
|
-
def self.base
|
|
243
|
-
Module.new do
|
|
244
|
-
include SerieImplementation
|
|
245
|
-
|
|
246
|
-
def has_source; false; end
|
|
247
|
-
private def mandatory_source; false; end
|
|
248
|
-
|
|
249
|
-
def has_sources; false; end
|
|
250
|
-
private def mandatory_sources; false; end
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# Creates configurable serie module with specified features.
|
|
255
|
-
#
|
|
256
|
-
# Factory method generating modules with:
|
|
257
|
-
#
|
|
258
|
-
# - Single source dependency (source: true)
|
|
259
|
-
# - Multiple sources dependency (sources: true)
|
|
260
|
-
# - Block attribute (block: true, smart_block: true)
|
|
261
|
-
#
|
|
262
|
-
# ## Source Support
|
|
263
|
-
#
|
|
264
|
-
# **source: true** adds:
|
|
265
|
-
#
|
|
266
|
-
# - `@source` instance variable
|
|
267
|
-
# - `#source` getter (or custom name via source_as:)
|
|
268
|
-
# - `#source=` setter with state validation
|
|
269
|
-
# - Automatic prototype/instance propagation
|
|
270
|
-
#
|
|
271
|
-
# ## Sources Support
|
|
272
|
-
#
|
|
273
|
-
# **sources: true** adds:
|
|
274
|
-
#
|
|
275
|
-
# - `@sources` instance variable (Hash or Array)
|
|
276
|
-
# - `#sources` getter/setter
|
|
277
|
-
# - Automatic state resolution from all sources
|
|
278
|
-
#
|
|
279
|
-
# ## Block Support
|
|
280
|
-
#
|
|
281
|
-
# **block: true** - Simple proc attribute
|
|
282
|
-
# **smart_block: true** - SmartProcBinder-wrapped block
|
|
283
|
-
#
|
|
284
|
-
# ## State Propagation
|
|
285
|
-
#
|
|
286
|
-
# Sources automatically propagate state:
|
|
287
|
-
#
|
|
288
|
-
# - Setting source to :prototype → marks self as :prototype
|
|
289
|
-
# - Setting source to :instance → marks self as :instance
|
|
290
|
-
# - Cloning propagates through source/sources
|
|
291
|
-
#
|
|
292
|
-
# @param source [Boolean] add single source dependency
|
|
293
|
-
# @param source_as [Symbol, nil] custom name for source attribute
|
|
294
|
-
# @param private_source [Boolean, nil] make source methods private
|
|
295
|
-
# @param mandatory_source [Boolean, nil] require source to be set
|
|
296
|
-
# @param sources [Boolean] add multiple sources dependency
|
|
297
|
-
# @param sources_as [Symbol, nil] custom name for sources attribute
|
|
298
|
-
# @param private_sources [Boolean, nil] make sources methods private
|
|
299
|
-
# @param mandatory_sources [Boolean, nil] require sources to be set
|
|
300
|
-
# @param smart_block [Boolean] add SmartProcBinder block support
|
|
301
|
-
# @param block [Boolean] add simple block support
|
|
302
|
-
# @param block_as [Symbol, nil] custom name for block attribute
|
|
303
|
-
#
|
|
304
|
-
# @return [Module] configured module with SerieImplementation
|
|
305
|
-
#
|
|
306
|
-
# @example Serie with single source
|
|
307
|
-
# class ReverseSerie
|
|
308
|
-
# include Serie.with(source: true)
|
|
309
|
-
#
|
|
310
|
-
# def _next_value
|
|
311
|
-
# # Process source.next_value
|
|
312
|
-
# end
|
|
313
|
-
# end
|
|
314
|
-
#
|
|
315
|
-
# @example Serie with block
|
|
316
|
-
# class MapSerie
|
|
317
|
-
# include Serie.with(source: true, smart_block: true)
|
|
318
|
-
#
|
|
319
|
-
# def _next_value
|
|
320
|
-
# value = source.next_value
|
|
321
|
-
# value ? @block.call(value) : nil
|
|
322
|
-
# end
|
|
323
|
-
# end
|
|
324
|
-
#
|
|
325
|
-
# @api private
|
|
326
|
-
def self.with(source: false,
|
|
327
|
-
source_as: nil,
|
|
328
|
-
private_source: nil,
|
|
329
|
-
mandatory_source: nil,
|
|
330
|
-
sources: false,
|
|
331
|
-
sources_as: nil,
|
|
332
|
-
private_sources: nil,
|
|
333
|
-
mandatory_sources: nil,
|
|
334
|
-
smart_block: false,
|
|
335
|
-
block: false,
|
|
336
|
-
block_as: nil)
|
|
337
|
-
|
|
338
|
-
source_as ||= :source
|
|
339
|
-
source_setter = (source_as.to_s + '=').to_sym
|
|
340
|
-
_mandatory_source = source if mandatory_source.nil?
|
|
341
|
-
|
|
342
|
-
sources_as ||= :sources
|
|
343
|
-
sources_setter = (sources_as.to_s + '=').to_sym
|
|
344
|
-
_mandatory_sources = sources if mandatory_sources.nil?
|
|
345
|
-
|
|
346
|
-
block_as ||= :proc
|
|
347
|
-
block_setter = (block_as.to_s + '=').to_sym
|
|
348
|
-
|
|
349
|
-
Module.new do
|
|
350
|
-
include SerieImplementation
|
|
351
|
-
|
|
352
|
-
if source
|
|
353
|
-
private def has_source; true; end
|
|
354
|
-
define_method(:mandatory_source) { _mandatory_source }
|
|
355
|
-
private :mandatory_source
|
|
356
|
-
|
|
357
|
-
define_method source_as do
|
|
358
|
-
@source
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
define_method source_setter do |serie|
|
|
362
|
-
unless @source.nil? || @source.undefined? || serie.state == @source.state
|
|
363
|
-
raise ArgumentError, "New serie for #{source_as} should be a #{@state} instead of a #{serie.state}"
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
@source = serie
|
|
367
|
-
mark_regarding! @source
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
if private_source
|
|
371
|
-
private source_as
|
|
372
|
-
private source_setter
|
|
373
|
-
end
|
|
374
|
-
else
|
|
375
|
-
private def has_source; false; end
|
|
376
|
-
private def mandatory_source; false; end
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
if sources
|
|
380
|
-
private def has_sources; true; end
|
|
381
|
-
define_method(:mandatory_sources) { _mandatory_sources }
|
|
382
|
-
private :mandatory_source
|
|
383
|
-
|
|
384
|
-
define_method sources_as do
|
|
385
|
-
@sources
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
define_method sources_setter do |series|
|
|
389
|
-
unless series.is_a?(Hash) || series.is_a?(Array)
|
|
390
|
-
raise ArgumentError, "New series for #{sources_as} should be a Hash or an Array instead of a #{series.class.name}"
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
@sources = series
|
|
394
|
-
try_to_resolve_undefined_state_if_needed
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
if private_sources
|
|
398
|
-
private sources_as
|
|
399
|
-
private sources_setter
|
|
400
|
-
end
|
|
401
|
-
else
|
|
402
|
-
private def has_sources; false; end
|
|
403
|
-
private def mandatory_sources; false; end
|
|
404
|
-
end
|
|
405
|
-
|
|
406
|
-
if smart_block
|
|
407
|
-
define_method block_as do |&block|
|
|
408
|
-
if block
|
|
409
|
-
@block = Extension::SmartProcBinder::SmartProcBinder.new(block)
|
|
410
|
-
else
|
|
411
|
-
@block.proc
|
|
412
|
-
end
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
define_method block_setter do |block|
|
|
416
|
-
@block = Extension::SmartProcBinder::SmartProcBinder.new(block)
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
elsif block
|
|
420
|
-
define_method block_as do |&block|
|
|
421
|
-
if block
|
|
422
|
-
@block = block
|
|
423
|
-
else
|
|
424
|
-
@block
|
|
425
|
-
end
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
define_method block_setter do |block|
|
|
429
|
-
@block = block
|
|
430
|
-
end
|
|
431
|
-
end
|
|
432
|
-
end
|
|
433
|
-
end
|
|
434
|
-
|
|
435
239
|
# Prototype/instance state management for Series.
|
|
436
240
|
#
|
|
437
241
|
# Implements the prototype/instance pattern enabling reusable serie
|
|
@@ -651,14 +455,14 @@ module Musa
|
|
|
651
455
|
|
|
652
456
|
# Converts serie and dependencies to prototype state.
|
|
653
457
|
#
|
|
654
|
-
# Called automatically during cloning. By default, handles
|
|
655
|
-
#
|
|
458
|
+
# Called automatically during cloning. By default, handles +@source+ and
|
|
459
|
+
# +@sources+ attributes automatically. Subclasses can override to add
|
|
656
460
|
# custom prototyping logic.
|
|
657
461
|
#
|
|
658
462
|
# ## Default Behavior
|
|
659
463
|
#
|
|
660
|
-
# - Calls
|
|
661
|
-
# - Calls
|
|
464
|
+
# - Calls +.prototype+ on +@source+ if present
|
|
465
|
+
# - Calls +.prototype+ on all +@sources+ elements (Array or Hash)
|
|
662
466
|
#
|
|
663
467
|
# @return [void]
|
|
664
468
|
#
|
|
@@ -677,13 +481,13 @@ module Musa
|
|
|
677
481
|
# Converts serie and dependencies to instance state.
|
|
678
482
|
#
|
|
679
483
|
# Called automatically during instance creation. By default, handles
|
|
680
|
-
#
|
|
484
|
+
# +@source+ and +@sources+ attributes automatically. Subclasses can
|
|
681
485
|
# override to add custom instancing logic.
|
|
682
486
|
#
|
|
683
487
|
# ## Default Behavior
|
|
684
488
|
#
|
|
685
|
-
# - Calls
|
|
686
|
-
# - Calls
|
|
489
|
+
# - Calls +.instance+ on +@source+ if present
|
|
490
|
+
# - Calls +.instance+ on all +@sources+ elements (Array or Hash)
|
|
687
491
|
#
|
|
688
492
|
# @return [void]
|
|
689
493
|
#
|
|
@@ -801,7 +605,7 @@ module Musa
|
|
|
801
605
|
# Attempts to resolve undefined state from sources.
|
|
802
606
|
#
|
|
803
607
|
# Called automatically before state queries. Resolves state based on
|
|
804
|
-
#
|
|
608
|
+
# +@source+ and +@sources+ dependencies:
|
|
805
609
|
#
|
|
806
610
|
# - All sources :prototype → :prototype
|
|
807
611
|
# - All sources :instance → :instance
|
|
@@ -1314,6 +1118,212 @@ module Musa
|
|
|
1314
1118
|
end
|
|
1315
1119
|
|
|
1316
1120
|
private_constant :SerieImplementation
|
|
1121
|
+
|
|
1122
|
+
# Base module for all Serie implementations.
|
|
1123
|
+
#
|
|
1124
|
+
# Provides the core Serie functionality without source or block support.
|
|
1125
|
+
# Include this module in classes that don't need source dependencies.
|
|
1126
|
+
#
|
|
1127
|
+
# @example Basic usage
|
|
1128
|
+
# class MySerie
|
|
1129
|
+
# include Serie::Base
|
|
1130
|
+
#
|
|
1131
|
+
# def initialize
|
|
1132
|
+
# init
|
|
1133
|
+
# mark_as_prototype!
|
|
1134
|
+
# end
|
|
1135
|
+
#
|
|
1136
|
+
# private def _next_value
|
|
1137
|
+
# # implementation
|
|
1138
|
+
# end
|
|
1139
|
+
# end
|
|
1140
|
+
#
|
|
1141
|
+
# @see WithSource For series with single source dependency
|
|
1142
|
+
# @see WithSources For series with multiple source dependencies
|
|
1143
|
+
module Base
|
|
1144
|
+
include SerieImplementation
|
|
1145
|
+
|
|
1146
|
+
private def has_source; false; end
|
|
1147
|
+
private def mandatory_source; false; end
|
|
1148
|
+
private def has_sources; false; end
|
|
1149
|
+
private def mandatory_sources; false; end
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
# Mixin for series with single source dependency.
|
|
1153
|
+
#
|
|
1154
|
+
# Provides `source` and `source=` accessors for series that depend on
|
|
1155
|
+
# one upstream source serie.
|
|
1156
|
+
#
|
|
1157
|
+
# @example Usage
|
|
1158
|
+
# class ProcessorSerie
|
|
1159
|
+
# include Serie::Base
|
|
1160
|
+
# include Serie::WithSource
|
|
1161
|
+
#
|
|
1162
|
+
# def initialize(source)
|
|
1163
|
+
# self.source = source
|
|
1164
|
+
# init
|
|
1165
|
+
# end
|
|
1166
|
+
# end
|
|
1167
|
+
#
|
|
1168
|
+
# @example Custom accessor name using alias
|
|
1169
|
+
# class MyCustomSerie
|
|
1170
|
+
# include Serie::Base
|
|
1171
|
+
# include Serie::WithSource
|
|
1172
|
+
# alias my_source source
|
|
1173
|
+
# alias my_source= source=
|
|
1174
|
+
# end
|
|
1175
|
+
#
|
|
1176
|
+
# @see WithSources For multiple source dependencies
|
|
1177
|
+
module WithSource
|
|
1178
|
+
private def has_source; true; end
|
|
1179
|
+
private def mandatory_source; true; end
|
|
1180
|
+
|
|
1181
|
+
# @return [Serie, nil] the upstream source serie
|
|
1182
|
+
def source
|
|
1183
|
+
@source
|
|
1184
|
+
end
|
|
1185
|
+
|
|
1186
|
+
# Sets the source serie.
|
|
1187
|
+
#
|
|
1188
|
+
# @param serie [Serie] source serie (must match current state)
|
|
1189
|
+
# @raise [ArgumentError] if state mismatch between source and this serie
|
|
1190
|
+
def source=(serie)
|
|
1191
|
+
unless @source.nil? || @source.undefined? || serie.state == @source.state
|
|
1192
|
+
raise ArgumentError, "New serie for source should be a #{@state} instead of a #{serie.state}"
|
|
1193
|
+
end
|
|
1194
|
+
@source = serie
|
|
1195
|
+
mark_regarding! @source
|
|
1196
|
+
end
|
|
1197
|
+
end
|
|
1198
|
+
|
|
1199
|
+
# Mixin for series with multiple source dependencies.
|
|
1200
|
+
#
|
|
1201
|
+
# Provides `sources` and `sources=` accessors for series that depend on
|
|
1202
|
+
# multiple upstream series (as Array or Hash).
|
|
1203
|
+
#
|
|
1204
|
+
# @example Usage with Array
|
|
1205
|
+
# class MergeSerie
|
|
1206
|
+
# include Serie::Base
|
|
1207
|
+
# include Serie::WithSources
|
|
1208
|
+
#
|
|
1209
|
+
# def initialize(*series)
|
|
1210
|
+
# self.sources = series
|
|
1211
|
+
# init
|
|
1212
|
+
# end
|
|
1213
|
+
# end
|
|
1214
|
+
#
|
|
1215
|
+
# @example Usage with Hash
|
|
1216
|
+
# class NamedSourcesSerie
|
|
1217
|
+
# include Serie::Base
|
|
1218
|
+
# include Serie::WithSources
|
|
1219
|
+
#
|
|
1220
|
+
# def initialize(melody:, rhythm:)
|
|
1221
|
+
# self.sources = { melody: melody, rhythm: rhythm }
|
|
1222
|
+
# init
|
|
1223
|
+
# end
|
|
1224
|
+
# end
|
|
1225
|
+
#
|
|
1226
|
+
# @see WithSource For single source dependency
|
|
1227
|
+
module WithSources
|
|
1228
|
+
private def has_sources; true; end
|
|
1229
|
+
private def mandatory_sources; true; end
|
|
1230
|
+
|
|
1231
|
+
# @return [Array<Serie>, Hash{Symbol => Serie}, nil] upstream source series
|
|
1232
|
+
def sources
|
|
1233
|
+
@sources
|
|
1234
|
+
end
|
|
1235
|
+
|
|
1236
|
+
# Sets the sources series.
|
|
1237
|
+
#
|
|
1238
|
+
# @param series [Array<Serie>, Hash{Symbol => Serie}] source series
|
|
1239
|
+
# @raise [ArgumentError] if series is not a Hash or Array
|
|
1240
|
+
def sources=(series)
|
|
1241
|
+
unless series.is_a?(Hash) || series.is_a?(Array)
|
|
1242
|
+
raise ArgumentError, "New series for sources should be a Hash or an Array instead of a #{series.class.name}"
|
|
1243
|
+
end
|
|
1244
|
+
@sources = series
|
|
1245
|
+
send(:try_to_resolve_undefined_state_if_needed)
|
|
1246
|
+
end
|
|
1247
|
+
end
|
|
1248
|
+
|
|
1249
|
+
# Mixin for series with block/proc attribute (simple version).
|
|
1250
|
+
#
|
|
1251
|
+
# Provides `proc` accessor for series that use a Proc directly
|
|
1252
|
+
# without SmartProcBinder wrapping.
|
|
1253
|
+
#
|
|
1254
|
+
# @example Usage
|
|
1255
|
+
# class MapperSerie
|
|
1256
|
+
# include Serie::Base
|
|
1257
|
+
# include Serie::WithBlock
|
|
1258
|
+
#
|
|
1259
|
+
# def initialize(&block)
|
|
1260
|
+
# self.proc = block
|
|
1261
|
+
# init
|
|
1262
|
+
# end
|
|
1263
|
+
# end
|
|
1264
|
+
#
|
|
1265
|
+
# @see WithSmartBlock For SmartProcBinder-wrapped blocks
|
|
1266
|
+
module WithBlock
|
|
1267
|
+
# Gets or sets the proc.
|
|
1268
|
+
#
|
|
1269
|
+
# @overload proc
|
|
1270
|
+
# @return [Proc, nil] the stored proc
|
|
1271
|
+
# @overload proc(&block)
|
|
1272
|
+
# @param block [Proc] block to store
|
|
1273
|
+
# @return [Proc] the stored block
|
|
1274
|
+
def proc(&block)
|
|
1275
|
+
block ? (@block = block) : @block
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
# Sets the proc directly.
|
|
1279
|
+
#
|
|
1280
|
+
# @param block [Proc] block to store
|
|
1281
|
+
def proc=(block)
|
|
1282
|
+
@block = block
|
|
1283
|
+
end
|
|
1284
|
+
end
|
|
1285
|
+
|
|
1286
|
+
# Mixin for series with SmartProcBinder-wrapped block attribute.
|
|
1287
|
+
#
|
|
1288
|
+
# Similar to {WithBlock} but wraps procs in SmartProcBinder for
|
|
1289
|
+
# flexible parameter binding.
|
|
1290
|
+
#
|
|
1291
|
+
# @example Usage
|
|
1292
|
+
# class SmartMapperSerie
|
|
1293
|
+
# include Serie::Base
|
|
1294
|
+
# include Serie::WithSmartBlock
|
|
1295
|
+
#
|
|
1296
|
+
# def initialize(&block)
|
|
1297
|
+
# self.proc = block
|
|
1298
|
+
# init
|
|
1299
|
+
# end
|
|
1300
|
+
# end
|
|
1301
|
+
#
|
|
1302
|
+
# @see WithBlock For simple proc storage without wrapping
|
|
1303
|
+
# @see Extension::SmartProcBinder::SmartProcBinder
|
|
1304
|
+
module WithSmartBlock
|
|
1305
|
+
# Gets or sets the proc with SmartProcBinder wrapping.
|
|
1306
|
+
#
|
|
1307
|
+
# @overload proc
|
|
1308
|
+
# @return [Proc, nil] the underlying proc (unwrapped)
|
|
1309
|
+
# @overload proc(&block)
|
|
1310
|
+
# @param block [Proc] block to wrap and store
|
|
1311
|
+
# @return [Extension::SmartProcBinder::SmartProcBinder] the wrapped binder
|
|
1312
|
+
def proc(&block)
|
|
1313
|
+
if block
|
|
1314
|
+
@block = Extension::SmartProcBinder::SmartProcBinder.new(block)
|
|
1315
|
+
else
|
|
1316
|
+
@block&.proc
|
|
1317
|
+
end
|
|
1318
|
+
end
|
|
1319
|
+
|
|
1320
|
+
# Sets the proc with SmartProcBinder wrapping.
|
|
1321
|
+
#
|
|
1322
|
+
# @param block [Proc] block to wrap and store
|
|
1323
|
+
def proc=(block)
|
|
1324
|
+
@block = Extension::SmartProcBinder::SmartProcBinder.new(block)
|
|
1325
|
+
end
|
|
1326
|
+
end
|
|
1317
1327
|
end
|
|
1318
1328
|
end
|
|
1319
1329
|
end
|
|
@@ -57,7 +57,8 @@ module Musa
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
class SyncBufferSerie
|
|
60
|
-
include Series::Serie
|
|
60
|
+
include Series::Serie::Base
|
|
61
|
+
include Series::Serie::WithSource
|
|
61
62
|
|
|
62
63
|
def initialize(serie)
|
|
63
64
|
self.source = serie
|
|
@@ -97,7 +98,7 @@ module Musa
|
|
|
97
98
|
end
|
|
98
99
|
|
|
99
100
|
class Buffer
|
|
100
|
-
include Series::Serie
|
|
101
|
+
include Series::Serie::Base
|
|
101
102
|
|
|
102
103
|
def initialize(history)
|
|
103
104
|
@history = history
|
|
@@ -145,7 +146,8 @@ module Musa
|
|
|
145
146
|
# modo fill_on_restart: cuando una serie hace restart, las demás no se ven afectadas porque siguen recibiendo
|
|
146
147
|
# todos los elementos de la serie original
|
|
147
148
|
|
|
148
|
-
include Series::Serie
|
|
149
|
+
include Series::Serie::Base
|
|
150
|
+
include Series::Serie::WithSource
|
|
149
151
|
|
|
150
152
|
def initialize(serie)
|
|
151
153
|
self.source = serie
|
|
@@ -243,10 +245,13 @@ module Musa
|
|
|
243
245
|
end
|
|
244
246
|
|
|
245
247
|
class Buffer
|
|
246
|
-
include Series::Serie
|
|
248
|
+
include Series::Serie::Base
|
|
249
|
+
include Series::Serie::WithSource
|
|
250
|
+
|
|
251
|
+
private :source, :source=
|
|
247
252
|
|
|
248
253
|
def initialize(base)
|
|
249
|
-
|
|
254
|
+
send(:source=, base)
|
|
250
255
|
init
|
|
251
256
|
end
|
|
252
257
|
|
|
@@ -47,7 +47,8 @@ module Musa
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
class Splitter
|
|
50
|
-
include Series::Serie
|
|
50
|
+
include Series::Serie::Base
|
|
51
|
+
include Series::Serie::WithSource
|
|
51
52
|
include Enumerable
|
|
52
53
|
|
|
53
54
|
private def has_source; true; end
|
|
@@ -74,7 +75,7 @@ module Musa
|
|
|
74
75
|
# @param key_or_index [Symbol, Integer] hash key or array index
|
|
75
76
|
#
|
|
76
77
|
# @return [Split] component serie
|
|
77
|
-
def
|
|
78
|
+
def get(key_or_index)
|
|
78
79
|
raise "Can't get a component because Splitter is a prototype. To get a component you need a Splitter instance." unless instance?
|
|
79
80
|
|
|
80
81
|
if @series.key?(key_or_index)
|
|
@@ -84,6 +85,8 @@ module Musa
|
|
|
84
85
|
end
|
|
85
86
|
end
|
|
86
87
|
|
|
88
|
+
alias_method :[], :get
|
|
89
|
+
|
|
87
90
|
# Iterates over component series.
|
|
88
91
|
#
|
|
89
92
|
# @yield [key, split] for hash mode, [split] for array mode
|
|
@@ -233,7 +236,7 @@ module Musa
|
|
|
233
236
|
private_constant :SplitterProxy
|
|
234
237
|
|
|
235
238
|
class Split
|
|
236
|
-
include Series::Serie
|
|
239
|
+
include Series::Serie::Base
|
|
237
240
|
|
|
238
241
|
def initialize(proxy, key_or_index)
|
|
239
242
|
@proxy = proxy
|