musa-dsl 0.14.18 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/README.md +5 -1
  4. data/lib/musa-dsl.rb +54 -11
  5. data/lib/musa-dsl/core-ext.rb +7 -13
  6. data/lib/musa-dsl/core-ext/array-explode-ranges.rb +15 -23
  7. data/lib/musa-dsl/core-ext/arrayfy.rb +30 -12
  8. data/lib/musa-dsl/core-ext/attribute-builder.rb +194 -0
  9. data/lib/musa-dsl/core-ext/deep-copy.rb +185 -0
  10. data/lib/musa-dsl/core-ext/dynamic-proxy.rb +44 -40
  11. data/lib/musa-dsl/core-ext/inspect-nice.rb +40 -22
  12. data/lib/musa-dsl/core-ext/smart-proc-binder.rb +108 -0
  13. data/lib/musa-dsl/core-ext/with.rb +26 -0
  14. data/lib/musa-dsl/datasets.rb +8 -3
  15. data/lib/musa-dsl/datasets/dataset.rb +3 -0
  16. data/lib/musa-dsl/datasets/delta-d.rb +12 -0
  17. data/lib/musa-dsl/datasets/e.rb +61 -0
  18. data/lib/musa-dsl/datasets/gdv.rb +51 -411
  19. data/lib/musa-dsl/datasets/gdvd.rb +179 -0
  20. data/lib/musa-dsl/datasets/helper.rb +41 -0
  21. data/lib/musa-dsl/datasets/p.rb +68 -0
  22. data/lib/musa-dsl/datasets/packed-v.rb +19 -0
  23. data/lib/musa-dsl/datasets/pdv.rb +22 -15
  24. data/lib/musa-dsl/datasets/ps.rb +113 -0
  25. data/lib/musa-dsl/datasets/score.rb +210 -0
  26. data/lib/musa-dsl/datasets/score/queriable.rb +48 -0
  27. data/lib/musa-dsl/datasets/score/render.rb +31 -0
  28. data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +160 -0
  29. data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +51 -0
  30. data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +153 -0
  31. data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +158 -0
  32. data/lib/musa-dsl/datasets/v.rb +23 -0
  33. data/lib/musa-dsl/generative.rb +5 -5
  34. data/lib/musa-dsl/generative/backboner.rb +274 -0
  35. data/lib/musa-dsl/generative/darwin.rb +102 -96
  36. data/lib/musa-dsl/generative/generative-grammar.rb +182 -187
  37. data/lib/musa-dsl/generative/markov.rb +56 -53
  38. data/lib/musa-dsl/generative/variatio.rb +234 -222
  39. data/lib/musa-dsl/logger.rb +1 -0
  40. data/lib/musa-dsl/logger/logger.rb +31 -0
  41. data/lib/musa-dsl/matrix.rb +1 -0
  42. data/lib/musa-dsl/matrix/matrix.rb +210 -0
  43. data/lib/musa-dsl/midi.rb +2 -2
  44. data/lib/musa-dsl/midi/midi-recorder.rb +54 -52
  45. data/lib/musa-dsl/midi/midi-voices.rb +183 -182
  46. data/lib/musa-dsl/music.rb +5 -5
  47. data/lib/musa-dsl/music/chord-definition.rb +54 -50
  48. data/lib/musa-dsl/music/chord-definitions.rb +13 -9
  49. data/lib/musa-dsl/music/chords.rb +236 -238
  50. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +187 -183
  51. data/lib/musa-dsl/music/scales.rb +331 -332
  52. data/lib/musa-dsl/musicxml.rb +1 -0
  53. data/lib/musa-dsl/musicxml/builder/attributes.rb +155 -0
  54. data/lib/musa-dsl/musicxml/builder/backup-forward.rb +45 -0
  55. data/lib/musa-dsl/musicxml/builder/direction.rb +322 -0
  56. data/lib/musa-dsl/musicxml/builder/helper.rb +90 -0
  57. data/lib/musa-dsl/musicxml/builder/measure.rb +137 -0
  58. data/lib/musa-dsl/musicxml/builder/note-complexities.rb +152 -0
  59. data/lib/musa-dsl/musicxml/builder/note.rb +577 -0
  60. data/lib/musa-dsl/musicxml/builder/part-group.rb +44 -0
  61. data/lib/musa-dsl/musicxml/builder/part.rb +67 -0
  62. data/lib/musa-dsl/musicxml/builder/pitched-note.rb +126 -0
  63. data/lib/musa-dsl/musicxml/builder/rest.rb +117 -0
  64. data/lib/musa-dsl/musicxml/builder/score-partwise.rb +120 -0
  65. data/lib/musa-dsl/musicxml/builder/typed-text.rb +43 -0
  66. data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +112 -0
  67. data/lib/musa-dsl/neumalang.rb +1 -1
  68. data/lib/musa-dsl/neumalang/datatypes.citrus +79 -0
  69. data/lib/musa-dsl/neumalang/neuma.citrus +165 -0
  70. data/lib/musa-dsl/neumalang/neumalang.citrus +32 -242
  71. data/lib/musa-dsl/neumalang/neumalang.rb +373 -142
  72. data/lib/musa-dsl/neumalang/process.citrus +21 -0
  73. data/lib/musa-dsl/neumalang/terminals.citrus +67 -0
  74. data/lib/musa-dsl/neumalang/vectors.citrus +23 -0
  75. data/lib/musa-dsl/neumas.rb +5 -0
  76. data/lib/musa-dsl/neumas/array-to-neumas.rb +34 -0
  77. data/lib/musa-dsl/neumas/neuma-decoder.rb +63 -0
  78. data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +57 -0
  79. data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +15 -0
  80. data/lib/musa-dsl/neumas/neumas.rb +37 -0
  81. data/lib/musa-dsl/neumas/string-to-neumas.rb +33 -0
  82. data/lib/musa-dsl/repl.rb +1 -1
  83. data/lib/musa-dsl/repl/repl.rb +105 -105
  84. data/lib/musa-dsl/sequencer.rb +1 -1
  85. data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +163 -136
  86. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +301 -286
  87. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +562 -270
  88. data/lib/musa-dsl/sequencer/base-sequencer-public.rb +199 -188
  89. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +77 -0
  90. data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +75 -0
  91. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +105 -85
  92. data/lib/musa-dsl/sequencer/timeslots.rb +34 -0
  93. data/lib/musa-dsl/series.rb +1 -1
  94. data/lib/musa-dsl/{core-ext → series}/array-to-serie.rb +1 -1
  95. data/lib/musa-dsl/series/base-series.rb +171 -168
  96. data/lib/musa-dsl/series/hash-serie-splitter.rb +134 -132
  97. data/lib/musa-dsl/series/holder-serie.rb +1 -1
  98. data/lib/musa-dsl/series/main-serie-constructors.rb +6 -1
  99. data/lib/musa-dsl/series/main-serie-operations.rb +807 -797
  100. data/lib/musa-dsl/series/proxy-serie.rb +6 -6
  101. data/lib/musa-dsl/series/queue-serie.rb +5 -5
  102. data/lib/musa-dsl/series/series.rb +2 -0
  103. data/lib/musa-dsl/transcription.rb +4 -0
  104. data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +227 -0
  105. data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +36 -0
  106. data/lib/musa-dsl/transcription/from-gdv.rb +17 -0
  107. data/lib/musa-dsl/transcription/transcription.rb +55 -0
  108. data/lib/musa-dsl/transport.rb +6 -6
  109. data/lib/musa-dsl/transport/clock.rb +26 -26
  110. data/lib/musa-dsl/transport/dummy-clock.rb +32 -30
  111. data/lib/musa-dsl/transport/external-tick-clock.rb +21 -20
  112. data/lib/musa-dsl/transport/input-midi-clock.rb +82 -80
  113. data/lib/musa-dsl/transport/timer-clock.rb +72 -71
  114. data/lib/musa-dsl/transport/timer.rb +28 -26
  115. data/lib/musa-dsl/transport/transport.rb +98 -94
  116. data/musa-dsl.gemspec +3 -3
  117. metadata +73 -24
  118. data/lib/musa-dsl/core-ext/array-apply-get.rb +0 -18
  119. data/lib/musa-dsl/core-ext/array-to-neumas.rb +0 -28
  120. data/lib/musa-dsl/core-ext/as-context-run.rb +0 -44
  121. data/lib/musa-dsl/core-ext/duplicate.rb +0 -134
  122. data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +0 -85
  123. data/lib/musa-dsl/core-ext/proc-nice.rb +0 -13
  124. data/lib/musa-dsl/core-ext/send-nice.rb +0 -21
  125. data/lib/musa-dsl/core-ext/string-to-neumas.rb +0 -27
  126. data/lib/musa-dsl/datasets/gdv-decorators.rb +0 -221
  127. data/lib/musa-dsl/generative/rules.rb +0 -282
  128. data/lib/musa-dsl/neuma.rb +0 -1
  129. data/lib/musa-dsl/neuma/neuma.rb +0 -181
@@ -2,193 +2,195 @@ module Musa
2
2
  # TODO: adapt to series prototyping
3
3
  # TODO: full test cases
4
4
 
5
- module SerieOperations
6
- def split(buffered: nil, master: nil)
7
- buffered ||= false
8
-
9
- return HashSplitter.new HashSplitter::KeyProxy.new(self) if master.nil? && !buffered
10
- return HashSplitter.new HashSplitter::MasterSlaveKeyProxy.new(self, master) if !master.nil? && !buffered
11
- return HashSplitter.new HashSplitter::BufferedKeyProxy.new(self) if buffered
12
- end
13
-
14
- class HashSplitter
15
- def initialize(proxy)
16
- @proxy = proxy
17
- @series = {}
5
+ module Series
6
+ module SerieOperations
7
+ def split(buffered: nil, master: nil)
8
+ buffered ||= false
9
+
10
+ return HashSplitter.new HashSplitter::KeyProxy.new(self) if master.nil? && !buffered
11
+ return HashSplitter.new HashSplitter::MasterSlaveKeyProxy.new(self, master) if !master.nil? && !buffered
12
+ return HashSplitter.new HashSplitter::BufferedKeyProxy.new(self) if buffered
18
13
  end
19
14
 
20
- def [](key)
21
- serie = if @series.key? key
22
- @series[key]
23
- else
24
- @series[key] = Splitted.new(@proxy, key: key)
25
- end
26
- end
27
-
28
- class KeyProxy
29
- def initialize(hash_serie)
30
- @serie = hash_serie.instance
31
- @values = {}
15
+ class HashSplitter
16
+ def initialize(proxy)
17
+ @proxy = proxy
18
+ @series = {}
32
19
  end
33
20
 
34
- def restart
35
- @serie.restart
36
- @values = {}
21
+ def [](key)
22
+ serie = if @series.key? key
23
+ @series[key]
24
+ else
25
+ @series[key] = Splitted.new(@proxy, key: key)
26
+ end
37
27
  end
38
28
 
39
- def next_value(key)
40
- return nil unless @values
29
+ class KeyProxy
30
+ def initialize(hash_serie)
31
+ @serie = hash_serie.instance
32
+ @values = {}
33
+ end
41
34
 
42
- value = @values[key]
35
+ def restart
36
+ @serie.restart
37
+ @values = {}
38
+ end
43
39
 
44
- if value.nil?
45
- before_values = @values.collect { |k, v| [k, v] unless v.nil? }.compact.to_h
40
+ def next_value(key)
41
+ return nil unless @values
46
42
 
47
- @values = @serie.next_value
48
- value = @values[key] if @values
43
+ value = @values[key]
49
44
 
50
- warn "Warning: splitted serie #{@serie} values #{before_values} are being lost" if !value.nil? && !before_values.empty?
51
- end
45
+ if value.nil?
46
+ before_values = @values.collect { |k, v| [k, v] unless v.nil? }.compact.to_h
52
47
 
53
- @values[key] = nil if @values
48
+ @values = @serie.next_value
49
+ value = @values[key] if @values
54
50
 
55
- value
56
- end
51
+ warn "Warning: splitted serie #{@serie} values #{before_values} are being lost" if !value.nil? && !before_values.empty?
52
+ end
57
53
 
58
- def peek_next_value(key)
59
- value = @values[key]
54
+ @values[key] = nil if @values
60
55
 
61
- if value.nil?
62
- peek_values = @serie.peek_next_value
63
- value = peek_values[key] if peek_values
56
+ value
64
57
  end
65
58
 
66
- value
67
- end
68
- end
59
+ def peek_next_value(key)
60
+ value = @values[key]
69
61
 
70
- class BufferedKeyProxy
71
- def initialize(hash_serie)
72
- @serie = hash_serie.instance
73
- @values = {}
74
- end
62
+ if value.nil?
63
+ peek_values = @serie.peek_next_value
64
+ value = peek_values[key] if peek_values
65
+ end
75
66
 
76
- def restart
77
- @serie.restart
78
- @values = {}
67
+ value
68
+ end
79
69
  end
80
70
 
81
- def next_value(key)
82
- value = nil
71
+ class BufferedKeyProxy
72
+ def initialize(hash_serie)
73
+ @serie = hash_serie.instance
74
+ @values = {}
75
+ end
76
+
77
+ def restart
78
+ @serie.restart
79
+ @values = {}
80
+ end
81
+
82
+ def next_value(key)
83
+ value = nil
83
84
 
84
- if @values[key].nil? || @values[key].empty?
85
- hash_value = @serie.next_value
85
+ if @values[key].nil? || @values[key].empty?
86
+ hash_value = @serie.next_value
86
87
 
87
- if hash_value
88
- hash_value.each do |k, v|
89
- @values[k] = [] if @values[k].nil?
90
- @values[k] << v
88
+ if hash_value
89
+ hash_value.each do |k, v|
90
+ @values[k] = [] if @values[k].nil?
91
+ @values[k] << v
92
+ end
91
93
  end
92
94
  end
95
+
96
+ value = @values[key].shift if @values[key]
97
+
98
+ value
93
99
  end
94
100
 
95
- value = @values[key].shift if @values[key]
101
+ def peek_next_value(key)
102
+ value = nil
96
103
 
97
- value
104
+ if @values[key] && !@values[key].empty?
105
+ value = @values[key].first
106
+ else
107
+ peek_values = @serie.peek_next_value
108
+ value = peek_values[key] if peek_values
109
+ end
110
+
111
+ value
112
+ end
98
113
  end
99
114
 
100
- def peek_next_value(key)
101
- value = nil
115
+ class MasterSlaveKeyProxy
116
+ def initialize(hash_serie, master)
117
+ @serie = hash_serie.instance
118
+ @master = master
119
+ @values = {}
120
+ @values_counter = {}
121
+ end
102
122
 
103
- if @values[key] && !@values[key].empty?
104
- value = @values[key].first
105
- else
106
- peek_values = @serie.peek_next_value
107
- value = peek_values[key] if peek_values
123
+ def restart
124
+ @serie.restart
125
+ @values = {}
126
+ @values_counter = {}
108
127
  end
109
128
 
110
- value
111
- end
112
- end
129
+ def next_value(key)
130
+ return nil unless @values
113
131
 
114
- class MasterSlaveKeyProxy
115
- def initialize(hash_serie, master)
116
- @serie = hash_serie.instance
117
- @master = master
118
- @values = {}
119
- @values_counter = {}
120
- end
132
+ value = @values[key]
121
133
 
122
- def restart
123
- @serie.restart
124
- @values = {}
125
- @values_counter = {}
126
- end
134
+ if value.nil?
135
+ @values = @serie.next_value
127
136
 
128
- def next_value(key)
129
- return nil unless @values
137
+ value = @values[key] if @values
130
138
 
131
- value = @values[key]
139
+ # warn "Info: splitted serie #{@serie} use count on next_value: #{@values_counter}"
140
+ @values_counter = {}
141
+ end
132
142
 
133
- if value.nil?
134
- @values = @serie.next_value
143
+ @values_counter[key] ||= 0
144
+ @values_counter[key] += 1
135
145
 
136
- value = @values[key] if @values
146
+ @values[key] = nil if key == @master && @values
137
147
 
138
- # warn "Info: splitted serie #{@serie} use count on next_value: #{@values_counter}"
139
- @values_counter = {}
148
+ value
140
149
  end
141
150
 
142
- @values_counter[key] ||= 0
143
- @values_counter[key] += 1
151
+ def peek_next_value(key)
152
+ return nil unless @values
144
153
 
145
- @values[key] = nil if key == @master && @values
146
-
147
- value
148
- end
154
+ value = @values[key]
149
155
 
150
- def peek_next_value(key)
151
- return nil unless @values
152
-
153
- value = @values[key]
156
+ if value.nil?
157
+ peek_values = @serie.peek_next_value
158
+ value = peek_values[key] if peek_values
159
+ end
154
160
 
155
- if value.nil?
156
- peek_values = @serie.peek_next_value
157
- value = peek_values[key] if peek_values
161
+ value
158
162
  end
159
-
160
- value
161
163
  end
162
- end
163
164
 
164
- class Splitted
165
- include Serie
165
+ class Splitted
166
+ include Serie
166
167
 
167
- def initialize(proxy, key:)
168
- @proxy = proxy
169
- @key = key
168
+ def initialize(proxy, key:)
169
+ @proxy = proxy
170
+ @key = key
170
171
 
171
- mark_as_instance!
172
- end
172
+ mark_as_instance!
173
+ end
173
174
 
174
- def _prototype
175
- raise PrototypingSerieError, 'Cannot get prototype of a splitted serie'
176
- end
175
+ def _prototype
176
+ raise PrototypingSerieError, 'Cannot get prototype of a splitted serie'
177
+ end
177
178
 
178
- def _restart
179
- @proxy.restart
180
- end
179
+ def _restart
180
+ @proxy.restart
181
+ end
181
182
 
182
- def next_value
183
- @proxy.next_value(@key)
184
- end
183
+ def next_value
184
+ @proxy.next_value(@key)
185
+ end
185
186
 
186
- def peek_next_value
187
- @proxy.peek_next_value(@key)
187
+ def peek_next_value
188
+ @proxy.peek_next_value(@key)
189
+ end
188
190
  end
189
191
  end
190
- end
191
192
 
192
- private_constant :HashSplitter
193
+ private_constant :HashSplitter
194
+ end
193
195
  end
194
196
  end
@@ -66,7 +66,7 @@ module Musa
66
66
 
67
67
  def method_missing(method_name, *args, **key_args, &block)
68
68
  if @hold && @hold.respond_to?(method_name)
69
- @hold.send_nice method_name, *args, **key_args, &block
69
+ @hold.send method_name, *args, **key_args, &block
70
70
  else
71
71
  super
72
72
  end
@@ -1,9 +1,14 @@
1
- require 'musa-dsl/core-ext/arrayfy'
1
+ require_relative '../core-ext/arrayfy'
2
+
3
+ using Musa::Extension::Arrayfy
4
+ using Musa::Extension::ExplodeRanges
2
5
 
3
6
  # TODO: añadir en for: steps: (nº de pasos en los que repartir el incremento)
4
7
 
5
8
  module Musa
6
9
  module Series
10
+ extend self
11
+
7
12
  def NIL
8
13
  NilSerie.new
9
14
  end
@@ -1,1151 +1,1161 @@
1
1
  module Musa
2
- module SerieOperations
2
+ module Series
3
+ module SerieOperations
4
+ def autorestart
5
+ Autorestart.new self
6
+ end
3
7
 
4
- def autorestart
5
- Autorestart.new self
6
- end
8
+ def repeat(times = nil, condition: nil, &condition_block)
9
+ condition ||= condition_block
7
10
 
8
- def repeat(times = nil, condition: nil, &condition_block)
9
- condition ||= condition_block
11
+ if times || condition
12
+ Repeater.new self, times, &condition
13
+ else
14
+ InfiniteRepeater.new self
15
+ end
16
+ end
10
17
 
11
- if times || condition
12
- Repeater.new self, times, &condition
13
- else
14
- InfiniteRepeater.new self
18
+ def max_size(length)
19
+ LengthLimiter.new self, length
15
20
  end
16
- end
17
21
 
18
- def max_size(length)
19
- LengthLimiter.new self, length
20
- end
22
+ def skip(length)
23
+ Skipper.new self, length
24
+ end
21
25
 
22
- def skip(length)
23
- Skipper.new self, length
24
- end
26
+ def flatten
27
+ Flattener.new self
28
+ end
25
29
 
26
- def flatten
27
- Flattener.new self
28
- end
30
+ def process_with(**parameters, &processor)
31
+ Processor.new self, parameters, &processor
32
+ end
29
33
 
30
- def process_with(**parameters, &processor)
31
- Processor.new self, parameters, &processor
32
- end
34
+ # TODO: test case
35
+ def hashify(*keys)
36
+ HashFromSeriesArray.new self, keys
37
+ end
33
38
 
34
- # TODO: test case
35
- def hashify(*keys)
36
- HashFromSeriesArray.new self, keys
37
- end
39
+ # TODO: test case
40
+ def shift(shift)
41
+ Shifter.new self, shift
42
+ end
38
43
 
39
- # TODO: test case
40
- def shift(shift)
41
- Shifter.new self, shift
42
- end
44
+ # TODO: test case
45
+ def lock
46
+ Locker.new self
47
+ end
43
48
 
44
- # TODO: test case
45
- def lock
46
- Locker.new self
47
- end
49
+ # TODO: test case
50
+ def reverse
51
+ Reverser.new self
52
+ end
48
53
 
49
- # TODO: test case
50
- def reverse
51
- Reverser.new self
52
- end
54
+ # TODO: test case
55
+ def randomize(random: nil)
56
+ random ||= Random.new
57
+ Randomizer.new self, random
58
+ end
53
59
 
54
- # TODO: test case
55
- def randomize(random: nil)
56
- random ||= Random.new
57
- Randomizer.new self, random
58
- end
60
+ def remove(block = nil, &yield_block)
61
+ # TODO make history an optional block parameter (via keyparametersprocedurebinder)
62
+ block ||= yield_block
63
+ Remover.new self, &block
64
+ end
59
65
 
60
- def remove(block = nil, &yield_block)
61
- # TODO make history an optional block parameter (via keyparametersprocedurebinder)
62
- block ||= yield_block
63
- Remover.new self, &block
64
- end
66
+ def select(block = nil, &yield_block)
67
+ # TODO add optional history (via keyparametersprocedurebinder)
68
+ block ||= yield_block
69
+ Selector.new self, &block
70
+ end
65
71
 
66
- def select(block = nil, &yield_block)
67
- # TODO add optional history (via keyparametersprocedurebinder)
68
- block ||= yield_block
69
- Selector.new self, &block
70
- end
72
+ # TODO: test case
73
+ def switch(*indexed_series, **hash_series)
74
+ Switcher.new self, indexed_series, hash_series
75
+ end
71
76
 
72
- # TODO: test case
73
- def switch(*indexed_series, **hash_series)
74
- Switcher.new self, indexed_series, hash_series
75
- end
77
+ def multiplex(*indexed_series, **hash_series)
78
+ MultiplexSelector.new self, indexed_series, hash_series
79
+ end
76
80
 
77
- def multiplex(*indexed_series, **hash_series)
78
- MultiplexSelector.new self, indexed_series, hash_series
79
- end
81
+ # TODO: test case
82
+ def switch_serie(*indexed_series, **hash_series)
83
+ SwitchFullSerie.new self, indexed_series, hash_series
84
+ end
80
85
 
81
- # TODO: test case
82
- def switch_serie(*indexed_series, **hash_series)
83
- SwitchFullSerie.new self, indexed_series, hash_series
84
- end
86
+ def after(*series)
87
+ Sequence.new [self, *series]
88
+ end
85
89
 
86
- def after(*series)
87
- Sequence.new [self, *series]
88
- end
90
+ def +(other)
91
+ Sequence.new [self, other]
92
+ end
89
93
 
90
- def +(other)
91
- Sequence.new [self, other]
92
- end
94
+ def cut(length)
95
+ Cutter.new self, length
96
+ end
93
97
 
94
- def cut(length)
95
- Cutter.new self, length
96
- end
98
+ def merge
99
+ MergeSerieOfSeries.new self
100
+ end
97
101
 
98
- def merge
99
- MergeSerieOfSeries.new self
100
- end
102
+ def with(block = nil, on_restart: nil, **with_series, &yield_block)
103
+ block ||= yield_block
104
+ ProcessWith.new self, with_series, on_restart, &block
105
+ end
101
106
 
102
- def with(block = nil, on_restart: nil, **with_series, &yield_block)
103
- block ||= yield_block
104
- ProcessWith.new self, with_series, on_restart, &block
105
- end
107
+ alias_method :eval, :with
108
+
109
+ def map(&yield_block)
110
+ ProcessWith.new self, &yield_block
111
+ end
106
112
 
107
- alias_method :eval, :with
113
+ # TODO: test case
114
+ def slave
115
+ slave_serie = Slave.new self
108
116
 
109
- def map(&yield_block)
110
- ProcessWith.new self, &yield_block
111
- end
117
+ @_slaves ||= []
118
+ @_slaves << slave_serie
112
119
 
113
- # TODO: test case
114
- def slave
115
- slave_serie = Slave.new self
120
+ slave_serie
121
+ end
116
122
 
117
- @_slaves ||= []
118
- @_slaves << slave_serie
123
+ ###
124
+ ### Implementation
125
+ ###
119
126
 
120
- slave_serie
121
- end
127
+ class ProcessWith
128
+ include Musa::Extension::SmartProcBinder
129
+ include Serie
122
130
 
123
- ###
124
- ### Implementation
125
- ###
131
+ attr_reader :source, :with_sources, :on_restart, :block
126
132
 
127
- class ProcessWith
128
- include Serie
133
+ def initialize(serie, with_series = nil, on_restart = nil, &block)
134
+ @source = serie
135
+ @with_sources = with_series || {}
136
+ @on_restart = on_restart
137
+ @block = SmartProcBinder.new(block) if block_given?
129
138
 
130
- attr_reader :source, :with_sources, :on_restart, :block
139
+ if @source.prototype?
140
+ @with_sources = @with_sources.transform_values { |s| s.prototype }
141
+ else
142
+ @with_sources = @with_sources.transform_values { |s| s.instance }
143
+ end
131
144
 
132
- def initialize(serie, with_series = nil, on_restart = nil, &block)
133
- @source = serie
134
- @with_sources = with_series || {}
135
- @on_restart = on_restart
136
- @block = KeyParametersProcedureBinder.new(block) if block_given?
145
+ mark_regarding! @source
146
+ end
137
147
 
138
- if @source.prototype?
148
+ def _prototype
149
+ @source = @source.prototype
139
150
  @with_sources = @with_sources.transform_values { |s| s.prototype }
140
- else
141
- @with_sources = @with_sources.transform_values { |s| s.instance }
142
151
  end
143
152
 
144
- mark_regarding! @source
145
- end
146
-
147
- def _prototype
148
- @source = @source.prototype
149
- @with_sources = @with_sources.transform_values { |s| s.prototype }
150
- end
151
-
152
- def _instance
153
- @source = @source.instance
154
- @with_sources = @with_sources.transform_values { |s| s.instance }
155
- end
153
+ def _instance
154
+ @source = @source.instance
155
+ @with_sources = @with_sources.transform_values { |s| s.instance }
156
+ end
156
157
 
157
- def _restart
158
- @source.restart
159
- @with_sources.values.each { |s| s.restart }
160
- @on_restart.call if @on_restart
161
- end
158
+ def _restart
159
+ @source.restart
160
+ @with_sources.values.each { |s| s.restart }
161
+ @on_restart.call if @on_restart
162
+ end
162
163
 
163
- def _next_value
164
- main = @source.next_value
165
- others = @with_sources.transform_values { |v| v.next_value }
164
+ def _next_value
165
+ main = @source.next_value
166
+ others = @with_sources.transform_values { |v| v.next_value }
166
167
 
167
- value = nil
168
+ value = nil
168
169
 
169
- if main && !others.values.include?(nil)
170
- if @block
171
- value = @block._call([main], others)
172
- else
173
- value = [main, others]
170
+ if main && !others.values.include?(nil)
171
+ if @block
172
+ value = @block._call([main], others)
173
+ else
174
+ value = [main, others]
175
+ end
174
176
  end
177
+
178
+ value
175
179
  end
176
180
 
177
- value
181
+ def infinite?
182
+ @source.infinite? && !@with_sources.values.find { |s| !s.infinite? }
183
+ end
178
184
  end
179
185
 
180
- def infinite?
181
- @source.infinite? && !@with_sources.values.find { |s| !s.infinite? }
182
- end
183
- end
186
+ private_constant :ProcessWith
184
187
 
185
- private_constant :ProcessWith
188
+ class Switcher
189
+ include Serie
186
190
 
187
- class Switcher
188
- include Serie
191
+ attr_accessor :selector, :sources
189
192
 
190
- attr_accessor :selector, :sources
193
+ def initialize(selector, indexed_series, hash_series)
191
194
 
192
- def initialize(selector, indexed_series, hash_series)
195
+ @selector = selector
196
+ get = @selector.prototype? ? :prototype : :instance
193
197
 
194
- @selector = selector
195
- get = @selector.prototype? ? :prototype : :instance
198
+ if indexed_series && !indexed_series.empty?
199
+ @sources = indexed_series.collect(&get)
200
+ elsif hash_series && !hash_series.empty?
201
+ @sources = hash_series.clone.transform_values(&get)
202
+ end
196
203
 
197
- if indexed_series && !indexed_series.empty?
198
- @sources = indexed_series.collect(&get)
199
- elsif hash_series && !hash_series.empty?
200
- @sources = hash_series.clone.transform_values(&get)
201
- end
204
+ if get == :_prototype
205
+ @sources.freeze
206
+ end
202
207
 
203
- if get == :_prototype
204
- @sources.freeze
208
+ mark_regarding! @selector
205
209
  end
206
210
 
207
- mark_regarding! @selector
208
- end
211
+ def _prototype
212
+ @selector = @selector.prototype
213
+ @sources = @sources.collect(&:prototype).freeze if @sources.is_a? Array
214
+ @sources.transform_values(&:prototype).freeze if @sources.is_a? Hash
215
+ end
209
216
 
210
- def _prototype
211
- @selector = @selector.prototype
212
- @sources = @sources.collect(&:prototype).freeze if @sources.is_a? Array
213
- @sources.transform_values(&:prototype).freeze if @sources.is_a? Hash
214
- end
217
+ def _instance
218
+ @selector = @selector.instance
219
+ @sources = @sources.collect(&:instance) if @sources.is_a? Array
220
+ @sources.transform_values(&:_instance) if @sources.is_a? Hash
221
+ end
215
222
 
216
- def _instance
217
- @selector = @selector.instance
218
- @sources = @sources.collect(&:instance) if @sources.is_a? Array
219
- @sources.transform_values(&:_instance) if @sources.is_a? Hash
220
- end
223
+ def _restart
224
+ @selector.restart
225
+ @sources.each(&:restart) if @sources.is_a? Array
226
+ @sources.each { |_key, serie| serie.restart } if @sources.is_a? Hash
227
+ end
221
228
 
222
- def _restart
223
- @selector.restart
224
- @sources.each(&:restart) if @sources.is_a? Array
225
- @sources.each { |_key, serie| serie.restart } if @sources.is_a? Hash
226
- end
229
+ def _next_value
230
+ value = nil
227
231
 
228
- def _next_value
229
- value = nil
232
+ index_or_key = @selector.next_value
230
233
 
231
- index_or_key = @selector.next_value
234
+ value = @sources[index_or_key].next_value unless index_or_key.nil?
232
235
 
233
- value = @sources[index_or_key].next_value unless index_or_key.nil?
236
+ value
237
+ end
234
238
 
235
- value
239
+ def infinite?
240
+ @selector.infinite? && @sources.any? { |serie| serie.infinite? }
241
+ end
236
242
  end
237
243
 
238
- def infinite?
239
- @selector.infinite? && @sources.any? { |serie| serie.infinite? }
240
- end
241
- end
244
+ private_constant :Switcher
242
245
 
243
- private_constant :Switcher
246
+ class MultiplexSelector
247
+ include Serie
244
248
 
245
- class MultiplexSelector
246
- include Serie
249
+ attr_accessor :selector, :sources
247
250
 
248
- attr_accessor :selector, :sources
251
+ def initialize(selector, indexed_series, hash_series)
252
+ @selector = selector
253
+ get = @selector.prototype? ? :prototype : :instance
249
254
 
250
- def initialize(selector, indexed_series, hash_series)
251
- @selector = selector
252
- get = @selector.prototype? ? :prototype : :instance
255
+ if indexed_series && !indexed_series.empty?
256
+ @sources = indexed_series.collect(&get)
257
+ elsif hash_series && !hash_series.empty?
258
+ @sources = hash_series.clone.transform_values(&get)
259
+ end
253
260
 
254
- if indexed_series && !indexed_series.empty?
255
- @sources = indexed_series.collect(&get)
256
- elsif hash_series && !hash_series.empty?
257
- @sources = hash_series.clone.transform_values(&get)
258
- end
261
+ _restart false
259
262
 
260
- _restart false
263
+ if get == :_prototype
264
+ @sources.freeze
265
+ end
261
266
 
262
- if get == :_prototype
263
- @sources.freeze
267
+ mark_regarding! @selector
264
268
  end
265
269
 
266
- mark_regarding! @selector
267
- end
270
+ def _prototype
271
+ @selector = @selector.prototype
272
+ @sources = @sources.collect(&:prototype).freeze if @sources.is_a? Array
273
+ @sources.transform_values(&:prototype).freeze if @sources.is_a? Hash
274
+ end
268
275
 
269
- def _prototype
270
- @selector = @selector.prototype
271
- @sources = @sources.collect(&:prototype).freeze if @sources.is_a? Array
272
- @sources.transform_values(&:prototype).freeze if @sources.is_a? Hash
273
- end
276
+ def _instance
277
+ @selector = @selector.instance
278
+ @sources = @sources.collect(&:instance) if @sources.is_a? Array
279
+ @sources.transform_values(&:_instance) if @sources.is_a? Hash
280
+ end
274
281
 
275
- def _instance
276
- @selector = @selector.instance
277
- @sources = @sources.collect(&:instance) if @sources.is_a? Array
278
- @sources.transform_values(&:_instance) if @sources.is_a? Hash
279
- end
282
+ def _restart(restart_sources = true)
283
+ @current_value = nil
280
284
 
281
- def _restart(restart_sources = true)
282
- @current_value = nil
285
+ if restart_sources
286
+ @selector.restart
287
+ @sources.each(&:restart) if @sources.is_a? Array
288
+ @sources.each { |_key, serie| serie.restart } if @sources.is_a? Hash
289
+ end
283
290
 
284
- if restart_sources
285
- @selector.restart
286
- @sources.each(&:restart) if @sources.is_a? Array
287
- @sources.each { |_key, serie| serie.restart } if @sources.is_a? Hash
291
+ @first = true
288
292
  end
289
293
 
290
- @first = true
291
- end
294
+ def _next_value
295
+ @current_value =
296
+ if @first || !@current_value.nil?
297
+ @first = false
298
+ index_or_key = @selector.next_value
299
+ unless index_or_key.nil?
300
+ @sources.each(&:next_value)
301
+ @sources[index_or_key].current_value
302
+ end
303
+ end
304
+ end
292
305
 
293
- def _next_value
294
- @current_value =
295
- if @first || !@current_value.nil?
296
- @first = false
297
- index_or_key = @selector.next_value
298
- unless index_or_key.nil?
299
- @sources.each(&:next_value)
300
- @sources[index_or_key].current_value
301
- end
302
- end
306
+ def infinite?
307
+ @selector.infinite? && @sources.any? { |serie| serie.infinite? }
308
+ end
303
309
  end
304
310
 
305
- def infinite?
306
- @selector.infinite? && @sources.any? { |serie| serie.infinite? }
307
- end
308
- end
311
+ private_constant :MultiplexSelector
309
312
 
310
- private_constant :MultiplexSelector
313
+ class SwitchFullSerie
314
+ include Serie
311
315
 
312
- class SwitchFullSerie
313
- include Serie
316
+ attr_accessor :selector, :sources
314
317
 
315
- attr_accessor :selector, :sources
318
+ def initialize(selector, indexed_series, hash_series)
319
+ @selector = selector
320
+ get = @selector.prototype? ? :prototype : :instance
316
321
 
317
- def initialize(selector, indexed_series, hash_series)
318
- @selector = selector
319
- get = @selector.prototype? ? :prototype : :instance
322
+ if indexed_series && !indexed_series.empty?
323
+ @sources = indexed_series.collect(&get)
324
+ elsif hash_series && !hash_series.empty?
325
+ @sources = hash_series.clone.transform_values(&get)
326
+ end
320
327
 
321
- if indexed_series && !indexed_series.empty?
322
- @sources = indexed_series.collect(&get)
323
- elsif hash_series && !hash_series.empty?
324
- @sources = hash_series.clone.transform_values(&get)
325
- end
328
+ if get == :_prototype
329
+ @sources.freeze
330
+ end
326
331
 
327
- if get == :_prototype
328
- @sources.freeze
332
+ mark_regarding! @selector
329
333
  end
330
334
 
331
- mark_regarding! @selector
332
- end
335
+ def _prototype
336
+ @selector = @selector.prototype
337
+ @sources = @sources.collect(&:prototype).freeze if @sources.is_a? Array
338
+ @sources.transform_values(&:prototype).freeze if @sources.is_a? Hash
339
+ end
333
340
 
334
- def _prototype
335
- @selector = @selector.prototype
336
- @sources = @sources.collect(&:prototype).freeze if @sources.is_a? Array
337
- @sources.transform_values(&:prototype).freeze if @sources.is_a? Hash
338
- end
341
+ def _instance
342
+ @selector = @selector.instance
343
+ @sources = @sources.collect(&:instance) if @sources.is_a? Array
344
+ @sources.transform_values(&:_instance) if @sources.is_a? Hash
345
+ end
339
346
 
340
- def _instance
341
- @selector = @selector.instance
342
- @sources = @sources.collect(&:instance) if @sources.is_a? Array
343
- @sources.transform_values(&:_instance) if @sources.is_a? Hash
344
- end
347
+ def _restart
348
+ @selector.restart
349
+ @sources.each(&:restart)
350
+ end
345
351
 
346
- def _restart
347
- @selector.restart
348
- @sources.each(&:restart)
349
- end
352
+ def _next_value
353
+ value = nil
350
354
 
351
- def _next_value
352
- value = nil
355
+ value = @sources[@index_or_key].next_value unless @index_or_key.nil?
353
356
 
354
- value = @sources[@index_or_key].next_value unless @index_or_key.nil?
357
+ if value.nil?
358
+ @index_or_key = @selector.next_value
355
359
 
356
- if value.nil?
357
- @index_or_key = @selector.next_value
360
+ value = next_value unless @index_or_key.nil?
361
+ end
358
362
 
359
- value = next_value unless @index_or_key.nil?
363
+ value
360
364
  end
361
365
 
362
- value
366
+ def infinite?
367
+ !!(@selector.infinite? || @sources.find(&:infinite?))
368
+ end
363
369
  end
364
370
 
365
- def infinite?
366
- !!(@selector.infinite? || @sources.find(&:infinite?))
367
- end
368
- end
371
+ private_constant :SwitchFullSerie
369
372
 
370
- private_constant :SwitchFullSerie
373
+ class InfiniteRepeater
374
+ include Serie
371
375
 
372
- class InfiniteRepeater
373
- include Serie
376
+ attr_reader :source
374
377
 
375
- attr_reader :source
378
+ def initialize(serie)
379
+ @source = serie
376
380
 
377
- def initialize(serie)
378
- @source = serie
381
+ mark_regarding! @source
382
+ end
379
383
 
380
- mark_regarding! @source
381
- end
384
+ def _prototype
385
+ @source = @source.prototype
386
+ end
382
387
 
383
- def _prototype
384
- @source = @source.prototype
385
- end
388
+ def _instance
389
+ @source = @source.instance
390
+ end
386
391
 
387
- def _instance
388
- @source = @source.instance
389
- end
392
+ def _restart
393
+ @source.restart
394
+ end
390
395
 
391
- def _restart
392
- @source.restart
393
- end
396
+ def _next_value
397
+ value = @source.next_value
394
398
 
395
- def _next_value
396
- value = @source.next_value
399
+ if value.nil?
400
+ @source.restart
401
+ value = @source.next_value
402
+ end
397
403
 
398
- if value.nil?
399
- @source.restart
400
- value = @source.next_value
404
+ value
401
405
  end
402
406
 
403
- value
404
- end
405
-
406
- def infinite?
407
- true
407
+ def infinite?
408
+ true
409
+ end
408
410
  end
409
- end
410
411
 
411
- private_constant :InfiniteRepeater
412
+ private_constant :InfiniteRepeater
412
413
 
413
- class Repeater
414
- include Serie
414
+ class Repeater
415
+ include Serie
415
416
 
416
- attr_reader :source, :times, :condition
417
+ attr_reader :source, :times, :condition
417
418
 
418
- def initialize(serie, times = nil, &condition_block)
419
- @source = serie
419
+ def initialize(serie, times = nil, &condition)
420
+ @source = serie
420
421
 
421
- @times = times
422
- @condition = condition_block
422
+ @times = times
423
+ @external_condition = condition
423
424
 
424
- update_condition
425
- _restart false
425
+ _restart false
426
+ @condition = calculate_condition
426
427
 
427
- mark_regarding! @source
428
- end
428
+ mark_regarding! @source
429
+ end
429
430
 
430
- def _prototype
431
- @source = @source.prototype
432
- end
431
+ def _prototype
432
+ @source = @source.prototype
433
+ @condition = calculate_condition
434
+ end
433
435
 
434
- def _instance
435
- @source = @source.instance
436
- end
436
+ def _instance
437
+ @source = @source.instance
438
+ @condition = calculate_condition
439
+ end
437
440
 
438
- def _restart(restart_sources = true)
439
- @count = 0
440
- @source.restart if restart_sources
441
- end
441
+ def _restart(restart_sources = true)
442
+ @count = 0
443
+ @source.restart if restart_sources
444
+ end
442
445
 
443
- def _next_value
444
- value = @source.next_value
446
+ def _next_value
447
+ value = @source.next_value
445
448
 
446
- if value.nil?
447
- @count += 1
449
+ if value.nil?
450
+ @count += 1
448
451
 
449
- if instance_eval &@condition
450
- @source.restart
451
- value = @source.next_value
452
+ if @condition.call
453
+ @source.restart
454
+ value = @source.next_value
455
+ end
452
456
  end
453
- end
454
457
 
455
- value
456
- end
458
+ value
459
+ end
457
460
 
458
- def infinite?
459
- @source.infinite?
460
- end
461
+ def infinite?
462
+ @source.infinite?
463
+ end
461
464
 
462
- private
465
+ private
463
466
 
464
- def update_condition
465
- @condition = proc { @count < @times } if @times && !@condition
466
- @condition ||= proc { false }
467
+ def calculate_condition
468
+ if @external_condition
469
+ @external_condition
470
+ elsif @times
471
+ proc { @count < @times }
472
+ else
473
+ proc { false }
474
+ end
475
+ end
467
476
  end
468
- end
469
477
 
470
- private_constant :Repeater
478
+ private_constant :Repeater
471
479
 
472
- class LengthLimiter
473
- include Serie
480
+ class LengthLimiter
481
+ include Serie
474
482
 
475
- attr_reader :source, :length
483
+ attr_reader :source, :length
476
484
 
477
- def initialize(serie, length)
478
- @source = serie
479
- @length = length
485
+ def initialize(serie, length)
486
+ @source = serie
487
+ @length = length
480
488
 
481
- _restart false
489
+ _restart false
482
490
 
483
- mark_regarding! @source
484
- end
491
+ mark_regarding! @source
492
+ end
485
493
 
486
- def _prototype
487
- @source = @source.prototype
488
- end
494
+ def _prototype
495
+ @source = @source.prototype
496
+ end
489
497
 
490
- def _instance
491
- @source = @source.instance
492
- end
498
+ def _instance
499
+ @source = @source.instance
500
+ end
493
501
 
494
- def _restart(restart_sources = true)
495
- @position = 0
496
- @source.restart if restart_sources
497
- end
502
+ def _restart(restart_sources = true)
503
+ @position = 0
504
+ @source.restart if restart_sources
505
+ end
498
506
 
499
- def _next_value
500
- if @position < @length
501
- @position += 1
502
- @source.next_value
507
+ def _next_value
508
+ if @position < @length
509
+ @position += 1
510
+ @source.next_value
511
+ end
503
512
  end
504
- end
505
513
 
506
- def infinite?
507
- false
514
+ def infinite?
515
+ false
516
+ end
508
517
  end
509
- end
510
518
 
511
- private_constant :LengthLimiter
519
+ private_constant :LengthLimiter
512
520
 
513
- class Skipper
514
- include Serie
521
+ class Skipper
522
+ include Serie
515
523
 
516
- attr_reader :source, :length
524
+ attr_reader :source, :length
517
525
 
518
- def initialize(serie, length)
519
- @source = serie
520
- @length = length
526
+ def initialize(serie, length)
527
+ @source = serie
528
+ @length = length
521
529
 
522
- _restart false
530
+ _restart false
523
531
 
524
- mark_regarding! @source
525
- end
532
+ mark_regarding! @source
533
+ end
526
534
 
527
- def _prototype
528
- @source = @source.prototype
529
- end
535
+ def _prototype
536
+ @source = @source.prototype
537
+ end
530
538
 
531
- def _instance
532
- @source = @source.instance
533
- end
539
+ def _instance
540
+ @source = @source.instance
541
+ end
534
542
 
535
- def _restart(restart_sources = true)
536
- @source.restart if restart_sources
537
- @first = true
538
- end
543
+ def _restart(restart_sources = true)
544
+ @source.restart if restart_sources
545
+ @first = true
546
+ end
539
547
 
540
- def _next_value
541
- @length.times { @source.next_value } if @first
542
- @first = nil
548
+ def _next_value
549
+ @length.times { @source.next_value } if @first
550
+ @first = nil
543
551
 
544
- @source.next_value
545
- end
552
+ @source.next_value
553
+ end
546
554
 
547
- def infinite?
548
- @source.infinite?
555
+ def infinite?
556
+ @source.infinite?
557
+ end
549
558
  end
550
- end
551
-
552
- private_constant :Skipper
553
559
 
554
- class Flattener
555
- include Serie
560
+ private_constant :Skipper
556
561
 
557
- attr_reader :source
558
-
559
- def initialize(serie)
560
- @source = serie
562
+ class Flattener
563
+ include Serie
561
564
 
562
- _restart false
565
+ attr_reader :source
563
566
 
564
- mark_regarding! @source
565
- end
567
+ def initialize(serie)
568
+ @source = serie
566
569
 
567
- def _prototype
568
- @source = @source.prototype
569
- _restart false
570
- end
570
+ _restart false
571
571
 
572
- def _instance
573
- @source = @source.instance
574
- _restart false
575
- end
572
+ mark_regarding! @source
573
+ end
576
574
 
577
- def _restart(restart_sources = true)
578
- if restart_sources
579
- @source.restart
580
- @restart_each_serie = true
581
- else
582
- @restart_each_serie = false
575
+ def _prototype
576
+ @source = @source.prototype
577
+ _restart false
583
578
  end
584
579
 
585
- @stack = [@source]
586
- end
580
+ def _instance
581
+ @source = @source.instance
582
+ _restart false
583
+ end
587
584
 
588
- def _next_value
589
- if @stack.last
590
- value = @stack.last.next_value
591
-
592
- case value
593
- when Serie
594
- value = value.instance
595
- value.restart if @restart_each_serie
596
- @stack.push(value)
597
- _next_value
598
- when nil
599
- @stack.pop
600
- _next_value
585
+ def _restart(restart_sources = true)
586
+ if restart_sources
587
+ @source.restart
588
+ @restart_each_serie = true
601
589
  else
602
- value
590
+ @restart_each_serie = false
591
+ end
592
+
593
+ @stack = [@source]
594
+ end
595
+
596
+ def _next_value
597
+ if @stack.last
598
+ value = @stack.last.next_value
599
+
600
+ case value
601
+ when Serie
602
+ value = value.instance
603
+ value.restart if @restart_each_serie
604
+ @stack.push(value)
605
+ _next_value
606
+ when nil
607
+ @stack.pop
608
+ _next_value
609
+ else
610
+ value
611
+ end
603
612
  end
604
613
  end
605
- end
606
614
 
607
- def infinite?
608
- @source.infinite? # TODO revisar porque las series hijas sí que pueden ser infinitas
615
+ def infinite?
616
+ @source.infinite? # TODO revisar porque las series hijas sí que pueden ser infinitas
617
+ end
609
618
  end
610
- end
611
619
 
612
- private_constant :Flattener
620
+ private_constant :Flattener
613
621
 
614
- class MergeSerieOfSeries
615
- include Serie
622
+ class MergeSerieOfSeries
623
+ include Serie
616
624
 
617
- attr_reader :source
625
+ attr_reader :source
618
626
 
619
- def initialize(serie)
620
- @source = serie
621
- _restart false
627
+ def initialize(serie)
628
+ @source = serie
629
+ _restart false
622
630
 
623
- mark_regarding! @source
624
- end
631
+ mark_regarding! @source
632
+ end
625
633
 
626
- def _prototype
627
- @source = @source.prototype
628
- end
634
+ def _prototype
635
+ @source = @source.prototype
636
+ end
629
637
 
630
- def _instance
631
- @source = @source.instance
632
- end
638
+ def _instance
639
+ @source = @source.instance
640
+ end
633
641
 
634
- def _restart(restart_sources = true)
635
- if restart_sources
636
- @source.restart
637
- @restart_each_serie = true
642
+ def _restart(restart_sources = true)
643
+ if restart_sources
644
+ @source.restart
645
+ @restart_each_serie = true
646
+ end
647
+ @current_serie = nil
638
648
  end
639
- @current_serie = nil
640
- end
641
649
 
642
- def _next_value
643
- value = nil
650
+ def _next_value
651
+ value = nil
644
652
 
645
- restart_current_serie_if_needed = false
653
+ restart_current_serie_if_needed = false
646
654
 
647
- if @current_serie.nil?
648
- @current_serie = @source.next_value
649
- @current_serie = @current_serie.instance if @current_serie
655
+ if @current_serie.nil?
656
+ @current_serie = @source.next_value
657
+ @current_serie = @current_serie.instance if @current_serie
650
658
 
651
- if @restart_each_serie
652
- @current_serie.restart if @current_serie
653
- else
654
- restart_current_serie_if_needed = true
659
+ if @restart_each_serie
660
+ @current_serie.restart if @current_serie
661
+ else
662
+ restart_current_serie_if_needed = true
663
+ end
655
664
  end
656
- end
657
665
 
658
- if @current_serie
659
- value = @current_serie.next_value
666
+ if @current_serie
667
+ value = @current_serie.next_value
660
668
 
661
- if value.nil?
662
- if restart_current_serie_if_needed
663
- @current_serie.restart
664
- else
665
- @current_serie = nil
666
- end
669
+ if value.nil?
670
+ if restart_current_serie_if_needed
671
+ @current_serie.restart
672
+ else
673
+ @current_serie = nil
674
+ end
667
675
 
668
- value = _next_value
676
+ value = _next_value
677
+ end
669
678
  end
670
- end
671
679
 
672
- value
680
+ value
681
+ end
673
682
  end
674
- end
675
683
 
676
- private_constant :MergeSerieOfSeries
684
+ private_constant :MergeSerieOfSeries
677
685
 
678
- class Processor
679
- include Serie
686
+ class Processor
687
+ include Musa::Extension::SmartProcBinder
688
+ include Serie
680
689
 
681
- attr_reader :source
690
+ attr_reader :source
682
691
 
683
- def initialize(serie, parameters, &processor)
684
- @source = serie
685
- @parameters = parameters
686
- @processor = KeyParametersProcedureBinder.new(processor)
692
+ def initialize(serie, parameters, &processor)
693
+ @source = serie
694
+ @parameters = parameters
695
+ @processor = SmartProcBinder.new(processor)
687
696
 
688
- _restart false
697
+ _restart false
689
698
 
690
- mark_regarding! @source
691
- end
699
+ mark_regarding! @source
700
+ end
692
701
 
693
- def _prototype
694
- @source = @source.prototype
695
- end
702
+ def _prototype
703
+ @source = @source.prototype
704
+ end
696
705
 
697
- def _instance
698
- @source = @source.instance
699
- end
706
+ def _instance
707
+ @source = @source.instance
708
+ end
700
709
 
701
- def _restart(restart_source = true)
702
- @source.restart if restart_source
703
- @pending_values = []
704
- end
710
+ def _restart(restart_source = true)
711
+ @source.restart if restart_source
712
+ @pending_values = []
713
+ end
705
714
 
706
- def _next_value
707
- if @pending_values.empty?
715
+ def _next_value
716
+ if @pending_values.empty?
708
717
 
709
- v = @source.next_value
718
+ v = @source.next_value
710
719
 
711
- if v.nil?
712
- nil
720
+ if v.nil?
721
+ nil
722
+ else
723
+ value = @processor.call(v, **@parameters)
724
+
725
+ if value.is_a?(Array)
726
+ @pending_values = value
727
+ value = _next_value
728
+ end
729
+
730
+ value
731
+ end
713
732
  else
714
- value = @processor.call(v, **@parameters)
733
+ value = @pending_values.shift
715
734
 
716
- if value.is_a?(Array)
717
- @pending_values = value
735
+ if value.nil?
718
736
  value = _next_value
719
737
  end
720
738
 
721
739
  value
722
740
  end
723
- else
724
- value = @pending_values.shift
725
-
726
- if value.nil?
727
- value = _next_value
728
- end
729
-
730
- value
731
741
  end
732
- end
733
742
 
734
- def infinite?
735
- @source.infinite?
743
+ def infinite?
744
+ @source.infinite?
745
+ end
736
746
  end
737
- end
738
-
739
- class Autorestart
740
- include Serie
741
747
 
742
- attr_reader :source
748
+ class Autorestart
749
+ include Serie
743
750
 
744
- def initialize(serie)
745
- @source = serie
751
+ attr_reader :source
746
752
 
747
- @restart_on_next = false
753
+ def initialize(serie)
754
+ @source = serie
748
755
 
749
- mark_regarding! @source
750
- end
756
+ @restart_on_next = false
751
757
 
752
- def _prototype
753
- @source = @source.prototype
754
- end
758
+ mark_regarding! @source
759
+ end
755
760
 
756
- def _instance
757
- @source = @source.instance
758
- end
761
+ def _prototype
762
+ @source = @source.prototype
763
+ end
759
764
 
760
- def _restart
761
- @source.restart
762
- end
765
+ def _instance
766
+ @source = @source.instance
767
+ end
763
768
 
764
- def _next_value
765
- if @restart_on_next
769
+ def _restart
766
770
  @source.restart
767
- @restart_on_next = false
768
771
  end
769
772
 
770
- value = @source.next_value
771
-
772
- @restart_on_next = value.nil?
773
-
774
- value
775
- end
776
- end
777
-
778
- private_constant :Autorestart
779
-
780
- class Cutter
781
- include Serie
782
-
783
- attr_reader :source, :length
784
-
785
- def initialize(serie, length)
786
- @source = serie
787
- @length = length
788
-
789
- mark_regarding! @source
790
- end
791
-
792
- def _prototype
793
- @source = @source.prototype
794
- end
795
-
796
- def _instance
797
- @source = @source.instance
798
- end
773
+ def _next_value
774
+ if @restart_on_next
775
+ @source.restart
776
+ @restart_on_next = false
777
+ end
799
778
 
800
- def _restart
801
- @source.restart
802
- end
779
+ value = @source.next_value
803
780
 
804
- def _next_value
805
- @previous.materialize if @previous
781
+ @restart_on_next = value.nil?
806
782
 
807
- @previous = CutSerie.new @source, @length if @source.peek_next_value
783
+ value
784
+ end
808
785
  end
809
786
 
810
- private
787
+ private_constant :Autorestart
811
788
 
812
- class CutSerie
789
+ class Cutter
813
790
  include Serie
814
791
 
792
+ attr_reader :source, :length
793
+
815
794
  def initialize(serie, length)
816
795
  @source = serie
817
796
  @length = length
818
797
 
819
- @values = []
820
- _restart
821
-
822
- mark_as_instance!
798
+ mark_regarding! @source
823
799
  end
824
800
 
825
801
  def _prototype
826
- raise PrototypingSerieError, 'Cannot get prototype of a cut serie'
802
+ @source = @source.prototype
803
+ end
804
+
805
+ def _instance
806
+ @source = @source.instance
827
807
  end
828
808
 
829
809
  def _restart
830
- @count = 0
810
+ @source.restart
831
811
  end
832
812
 
833
813
  def _next_value
834
- value ||= @values[@count]
835
- value ||= @values[@count] = @source.next_value if @count < @length
814
+ @previous.materialize if @previous
836
815
 
837
- @count += 1
838
-
839
- value
816
+ @previous = CutSerie.new @source, @length if @source.peek_next_value
840
817
  end
841
818
 
842
- def materialize
843
- (@values.size..@length - 1).each { |i| @values[i] = @source.next_value }
819
+ private
820
+
821
+ class CutSerie
822
+ include Serie
823
+
824
+ def initialize(serie, length)
825
+ @source = serie
826
+ @length = length
827
+
828
+ @values = []
829
+ _restart
830
+
831
+ mark_as_instance!
832
+ end
833
+
834
+ def _prototype
835
+ raise PrototypingSerieError, 'Cannot get prototype of a cut serie'
836
+ end
837
+
838
+ def _restart
839
+ @count = 0
840
+ end
841
+
842
+ def _next_value
843
+ value ||= @values[@count]
844
+ value ||= @values[@count] = @source.next_value if @count < @length
845
+
846
+ @count += 1
847
+
848
+ value
849
+ end
850
+
851
+ def materialize
852
+ (@values.size..@length - 1).each { |i| @values[i] = @source.next_value }
853
+ end
844
854
  end
845
855
  end
846
- end
847
856
 
848
- private_constant :Cutter
857
+ private_constant :Cutter
849
858
 
850
- class Locker
851
- include Serie
859
+ class Locker
860
+ include Serie
852
861
 
853
- attr_reader :source
862
+ attr_reader :source
854
863
 
855
- def initialize(serie)
856
- @source = serie
857
- @values = []
858
- @first_round = true
864
+ def initialize(serie)
865
+ @source = serie
866
+ @values = []
867
+ @first_round = true
859
868
 
860
- _restart
869
+ _restart
861
870
 
862
- mark_regarding! @source
863
- end
871
+ mark_regarding! @source
872
+ end
864
873
 
865
- def _prototype
866
- @source = @source.prototype
867
- end
874
+ def _prototype
875
+ @source = @source.prototype
876
+ end
868
877
 
869
- def _instance
870
- @source = @source.instance
871
- end
878
+ def _instance
879
+ @source = @source.instance
880
+ end
872
881
 
873
- def _restart
874
- @index = 0
875
- end
882
+ def _restart
883
+ @index = 0
884
+ end
876
885
 
877
- def _next_value
878
- if @first_round
879
- value = @source.next_value
886
+ def _next_value
887
+ if @first_round
888
+ value = @source.next_value
880
889
 
881
- @first_round = false if value.nil?
882
- @values << value unless value.nil?
883
- else
884
- if @index < @values.size
885
- value = @values[@index]
886
- @index += 1
890
+ @first_round = false if value.nil?
891
+ @values << value unless value.nil?
887
892
  else
888
- value = nil
893
+ if @index < @values.size
894
+ value = @values[@index]
895
+ @index += 1
896
+ else
897
+ value = nil
898
+ end
889
899
  end
890
- end
891
900
 
892
- value
901
+ value
902
+ end
893
903
  end
894
- end
895
904
 
896
- private_constant :Locker
905
+ private_constant :Locker
897
906
 
898
- class Reverser
899
- include Serie
907
+ class Reverser
908
+ include Serie
900
909
 
901
- attr_reader :source
910
+ attr_reader :source
902
911
 
903
- def initialize(serie)
904
- @source = serie
905
- _restart false, false
912
+ def initialize(serie)
913
+ @source = serie
914
+ _restart false, false
906
915
 
907
- mark_regarding! @source
908
- end
916
+ mark_regarding! @source
917
+ end
909
918
 
910
- def _prototype
911
- @source = @source.prototype
912
- end
919
+ def _prototype
920
+ @source = @source.prototype
921
+ end
913
922
 
914
- def _instance
915
- @source = @source.instance
916
- _restart false, true
917
- end
923
+ def _instance
924
+ @source = @source.instance
925
+ _restart false, true
926
+ end
918
927
 
919
- def _restart(restart_sources = true, get_reversed = true)
920
- @source.restart if restart_sources
921
- @reversed = FromArray.new(next_values_array_of(@source).reverse).instance if get_reversed
922
- end
928
+ def _restart(restart_sources = true, get_reversed = true)
929
+ @source.restart if restart_sources
930
+ @reversed = FromArray.new(next_values_array_of(@source).reverse).instance if get_reversed
931
+ end
923
932
 
924
- def _next_value
925
- @reversed.next_value
926
- end
933
+ def _next_value
934
+ @reversed.next_value
935
+ end
927
936
 
928
- private
937
+ private
929
938
 
930
- def next_values_array_of(serie)
931
- array = []
939
+ def next_values_array_of(serie)
940
+ array = []
932
941
 
933
- until (value = serie.next_value).nil?
934
- array << value
935
- end
942
+ until (value = serie.next_value).nil?
943
+ array << value
944
+ end
936
945
 
937
- array
946
+ array
947
+ end
938
948
  end
939
- end
940
949
 
941
- private_constant :Reverser
950
+ private_constant :Reverser
942
951
 
943
- class Randomizer
944
- include Serie
952
+ class Randomizer
953
+ include Serie
945
954
 
946
- attr_reader :source, :random
955
+ attr_reader :source, :random
947
956
 
948
- def initialize(serie, random)
949
- @source = serie
950
- @random = random
957
+ def initialize(serie, random)
958
+ @source = serie
959
+ @random = random
951
960
 
952
- _restart false
961
+ _restart false
953
962
 
954
- mark_regarding! @source
955
- end
963
+ mark_regarding! @source
964
+ end
956
965
 
957
- def _prototype
958
- @source = @source.prototype
959
- end
966
+ def _prototype
967
+ @source = @source.prototype
968
+ end
960
969
 
961
- def _instance
962
- @source = @source.instance
963
- end
970
+ def _instance
971
+ @source = @source.instance
972
+ end
964
973
 
965
- def _restart(restart_sources = true)
966
- @source.restart if restart_sources
967
- @values = @source.to_a
968
- end
974
+ def _restart(restart_sources = true)
975
+ @source.restart if restart_sources
976
+ @values = @source.to_a
977
+ end
969
978
 
970
- def _next_value
971
- _restart(false) if @needs_restart
979
+ def _next_value
980
+ _restart(false) if @needs_restart
972
981
 
973
- if !@values.empty?
974
- position = @random.rand(0...@values.size)
975
- value = @values[position]
982
+ if !@values.empty?
983
+ position = @random.rand(0...@values.size)
984
+ value = @values[position]
976
985
 
977
- @values.delete_at position
978
- else
979
- value = nil
980
- end
986
+ @values.delete_at position
987
+ else
988
+ value = nil
989
+ end
981
990
 
982
- value
991
+ value
992
+ end
983
993
  end
984
- end
985
994
 
986
- private_constant :Randomizer
995
+ private_constant :Randomizer
987
996
 
988
- class Shifter
989
- include Serie
997
+ class Shifter
998
+ include Serie
990
999
 
991
- attr_reader :source, :shift
1000
+ attr_reader :source, :shift
992
1001
 
993
- def initialize(serie, shift)
994
- raise ArgumentError, "cannot shift to right an infinite serie #{serie}" if shift > 0 && serie.infinite?
995
- raise ArgumentError, 'cannot shift to right: function not yet implemented' if shift > 0
1002
+ def initialize(serie, shift)
1003
+ raise ArgumentError, "cannot shift to right an infinite serie #{serie}" if shift > 0 && serie.infinite?
1004
+ raise ArgumentError, 'cannot shift to right: function not yet implemented' if shift > 0
996
1005
 
997
- @source = serie
998
- @shift = shift
1006
+ @source = serie
1007
+ @shift = shift
999
1008
 
1000
- _restart false
1009
+ _restart false
1001
1010
 
1002
- mark_regarding! @source
1003
- end
1011
+ mark_regarding! @source
1012
+ end
1004
1013
 
1005
- def _prototype
1006
- @source = @source.prototype
1007
- end
1014
+ def _prototype
1015
+ @source = @source.prototype
1016
+ end
1008
1017
 
1009
- def _instance
1010
- @source = @source.instance
1011
- end
1018
+ def _instance
1019
+ @source = @source.instance
1020
+ end
1012
1021
 
1013
- def _restart(restart_sources = true)
1014
- @source.restart if restart_sources
1022
+ def _restart(restart_sources = true)
1023
+ @source.restart if restart_sources
1015
1024
 
1016
- @shifted = []
1017
- @shift.abs.times { @shifted << @source.next_value } if @shift < 0
1018
- end
1025
+ @shifted = []
1026
+ @shift.abs.times { @shifted << @source.next_value } if @shift < 0
1027
+ end
1019
1028
 
1020
- def _next_value
1021
- value = @source.next_value
1022
- return value unless value.nil?
1029
+ def _next_value
1030
+ value = @source.next_value
1031
+ return value unless value.nil?
1023
1032
 
1024
- @shifted.shift
1033
+ @shifted.shift
1034
+ end
1025
1035
  end
1026
- end
1027
1036
 
1028
- private_constant :Shifter
1037
+ private_constant :Shifter
1029
1038
 
1030
- class Remover
1031
- include Serie
1039
+ class Remover
1040
+ include Serie
1032
1041
 
1033
- attr_reader :source
1042
+ attr_reader :source
1034
1043
 
1035
- def initialize(serie, &block)
1036
- @source = serie
1037
- @block = block
1038
- @history = []
1044
+ def initialize(serie, &block)
1045
+ @source = serie
1046
+ @block = block
1047
+ @history = []
1039
1048
 
1040
- _restart false
1049
+ _restart false
1041
1050
 
1042
- mark_regarding! @source
1043
- end
1051
+ mark_regarding! @source
1052
+ end
1044
1053
 
1045
- def _prototype
1046
- @source = @source.prototype
1047
- end
1054
+ def _prototype
1055
+ @source = @source.prototype
1056
+ end
1048
1057
 
1049
- def _instance
1050
- @source = @source.instance
1051
- end
1058
+ def _instance
1059
+ @source = @source.instance
1060
+ end
1052
1061
 
1053
- def _restart(restart_sources = true)
1054
- @source.restart if restart_sources
1055
- @history.clear
1056
- end
1062
+ def _restart(restart_sources = true)
1063
+ @source.restart if restart_sources
1064
+ @history.clear
1065
+ end
1057
1066
 
1058
- def _next_value
1059
- if value = @source.next_value
1060
- while @block.call(value, @history)
1067
+ def _next_value
1068
+ if value = @source.next_value
1069
+ while @block.call(value, @history)
1070
+ @history << value
1071
+ value = @source.next_value
1072
+ end
1061
1073
  @history << value
1062
- value = @source.next_value
1063
1074
  end
1064
- @history << value
1075
+ value
1065
1076
  end
1066
- value
1067
1077
  end
1068
- end
1069
1078
 
1070
- private_constant :Remover
1079
+ private_constant :Remover
1071
1080
 
1072
- class Selector
1073
- include Serie
1081
+ class Selector
1082
+ include Serie
1074
1083
 
1075
- attr_reader :source
1084
+ attr_reader :source
1076
1085
 
1077
- def initialize(serie, &block)
1078
- @source = serie
1079
- @block = block
1086
+ def initialize(serie, &block)
1087
+ @source = serie
1088
+ @block = block
1080
1089
 
1081
- _restart false
1090
+ _restart false
1082
1091
 
1083
- mark_regarding! @source
1084
- end
1092
+ mark_regarding! @source
1093
+ end
1085
1094
 
1086
- def _prototype
1087
- @source = @source.prototype
1088
- end
1095
+ def _prototype
1096
+ @source = @source.prototype
1097
+ end
1089
1098
 
1090
- def _instance
1091
- @source = @source.instance
1092
- end
1099
+ def _instance
1100
+ @source = @source.instance
1101
+ end
1093
1102
 
1094
- def _restart(restart_sources = true)
1095
- @source.restart if restart_sources
1096
- end
1103
+ def _restart(restart_sources = true)
1104
+ @source.restart if restart_sources
1105
+ end
1097
1106
 
1098
- def _next_value
1099
- value = @source.next_value
1100
- until value.nil? || @block.call(value)
1107
+ def _next_value
1101
1108
  value = @source.next_value
1109
+ until value.nil? || @block.call(value)
1110
+ value = @source.next_value
1111
+ end
1112
+ value
1102
1113
  end
1103
- value
1104
1114
  end
1105
- end
1106
1115
 
1107
- private_constant :Selector
1116
+ private_constant :Selector
1108
1117
 
1109
- class HashFromSeriesArray
1110
- include Serie
1118
+ class HashFromSeriesArray
1119
+ include Serie
1111
1120
 
1112
- attr_reader :source, :keys
1121
+ attr_reader :source, :keys
1113
1122
 
1114
- def initialize(serie, keys)
1115
- @source = serie
1116
- @keys = keys
1117
- _restart false
1123
+ def initialize(serie, keys)
1124
+ @source = serie
1125
+ @keys = keys
1126
+ _restart false
1118
1127
 
1119
- mark_regarding! @source
1120
- end
1128
+ mark_regarding! @source
1129
+ end
1121
1130
 
1122
- def _prototype
1123
- @source = @source.prototype
1124
- end
1131
+ def _prototype
1132
+ @source = @source.prototype
1133
+ end
1125
1134
 
1126
- def _instance
1127
- @source = @source.instance
1128
- end
1135
+ def _instance
1136
+ @source = @source.instance
1137
+ end
1129
1138
 
1130
- def _restart(restart_sources = true)
1131
- @source.restart if restart_sources
1132
- end
1139
+ def _restart(restart_sources = true)
1140
+ @source.restart if restart_sources
1141
+ end
1133
1142
 
1134
- def _next_value
1135
- array = @source.next_value
1143
+ def _next_value
1144
+ array = @source.next_value
1136
1145
 
1137
- return nil unless array
1146
+ return nil unless array
1138
1147
 
1139
- value = array.length.times.collect { |i| [@keys[i], array[i]] }.to_h
1148
+ value = array.length.times.collect { |i| [@keys[i], array[i]] }.to_h
1140
1149
 
1141
- if value.find { |_key, value| value.nil? }
1142
- nil
1143
- else
1144
- value
1150
+ if value.find { |_key, value| value.nil? }
1151
+ nil
1152
+ else
1153
+ value
1154
+ end
1145
1155
  end
1146
1156
  end
1147
- end
1148
1157
 
1149
- private_constant :HashFromSeriesArray
1158
+ private_constant :HashFromSeriesArray
1159
+ end
1150
1160
  end
1151
1161
  end