musa-dsl 0.23.1 → 0.23.6
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 +2 -0
- data/lib/musa-dsl/series/base-series.rb +3 -3
- data/lib/musa-dsl/series/buffer-serie.rb +7 -8
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +33 -18
- data/lib/musa-dsl/series/main-serie-constructors.rb +1 -1
- data/lib/musa-dsl/series/main-serie-operations.rb +43 -0
- data/lib/musa-dsl/series/proxy-serie.rb +9 -5
- data/lib/musa-dsl/series/series-composer.rb +243 -55
- data/musa-dsl.gemspec +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4151142ca6664ad550224f1ab9af55f31ce8982ff24cd4bfdd5bcd02bd45756
|
4
|
+
data.tar.gz: 9c2f01bb75266047984017e7edbd7f18ed353c34321b197af0faf7a3e385449a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b02d2620956fd954a7435bb7b6888d7107d02b7e57722a0f5e2f84c57f38576eab3a3bc5972b058387bcf4ad92833acce44d60c2808f36690e865b2ac776d38
|
7
|
+
data.tar.gz: 6a13c17fb864649fe6881e5ee3d34f2c1c48ada65b1640835310fb1658897d43a631cb63c30a186c7fa71bf3cee809ddd46627a36869a25a0a94099ea079bcb0
|
data/Gemfile
CHANGED
@@ -38,12 +38,12 @@ module Musa
|
|
38
38
|
include SerieImplementation
|
39
39
|
|
40
40
|
if source
|
41
|
-
define_method source_as do
|
41
|
+
define_method source_as do
|
42
42
|
@source
|
43
43
|
end
|
44
44
|
|
45
45
|
define_method source_setter do |serie|
|
46
|
-
raise ArgumentError, "New
|
46
|
+
raise ArgumentError, "New #{source_as} should be a #{@get}" unless @source.nil? || @source.prototype? == serie&.prototype?
|
47
47
|
|
48
48
|
serie ||= Musa::Series::Constructors.NIL
|
49
49
|
@get = serie&.instance? ? :instance : :prototype
|
@@ -294,7 +294,7 @@ module Musa
|
|
294
294
|
@source&.infinite? || false
|
295
295
|
end
|
296
296
|
|
297
|
-
def to_a(
|
297
|
+
def to_a(duplicate: nil, recursive: nil, restart: nil, dr: nil)
|
298
298
|
recursive ||= false
|
299
299
|
|
300
300
|
dr = instance? if dr.nil?
|
@@ -117,18 +117,18 @@ module Musa
|
|
117
117
|
@buffer
|
118
118
|
end
|
119
119
|
|
120
|
-
private def _restart(
|
121
|
-
raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless
|
120
|
+
private def _restart(buffer)
|
121
|
+
raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless buffer
|
122
122
|
return if @source_just_restarted
|
123
123
|
|
124
|
-
next_nil = @nils.find { |_| _ >
|
124
|
+
next_nil = @nils.find { |_| _ > buffer.index }
|
125
125
|
|
126
|
-
if next_nil &&
|
127
|
-
|
126
|
+
if next_nil && buffer.index < next_nil
|
127
|
+
buffer.last_nil_index = buffer.index = next_nil
|
128
128
|
|
129
129
|
else
|
130
130
|
until _next_value.nil?; end
|
131
|
-
|
131
|
+
buffer.last_nil_index = buffer.index = @nils.last
|
132
132
|
end
|
133
133
|
|
134
134
|
clear_old_history
|
@@ -216,8 +216,7 @@ module Musa
|
|
216
216
|
@index += 1
|
217
217
|
value = @history[@index]
|
218
218
|
else
|
219
|
-
@source.next_value
|
220
|
-
value = _next_value
|
219
|
+
value = _next_value unless @source.next_value.nil?
|
221
220
|
end
|
222
221
|
|
223
222
|
if value.nil?
|
@@ -1,19 +1,32 @@
|
|
1
1
|
module Musa
|
2
2
|
module Series::Operations
|
3
3
|
def split
|
4
|
-
Splitter.new(
|
4
|
+
Splitter.new(self)
|
5
5
|
end
|
6
6
|
|
7
7
|
class Splitter
|
8
8
|
include Enumerable
|
9
|
+
include Series::Serie::Prototyping
|
9
10
|
|
10
|
-
def initialize(
|
11
|
-
@
|
11
|
+
def initialize(source)
|
12
|
+
@source = source
|
12
13
|
@series = {}
|
13
14
|
end
|
14
15
|
|
16
|
+
def source=(serie)
|
17
|
+
@source = serie
|
18
|
+
@proxy.source = @source if @proxy
|
19
|
+
end
|
20
|
+
|
21
|
+
protected def _instance!
|
22
|
+
super
|
23
|
+
@proxy = SplitterProxy.new(@source)
|
24
|
+
end
|
25
|
+
|
15
26
|
def [](key_or_index)
|
16
|
-
|
27
|
+
raise "Can't get a component because Splitter is a prototype. To get a component you need a Splitter instance." unless @is_instance
|
28
|
+
|
29
|
+
if @series.key?(key_or_index)
|
17
30
|
@series[key_or_index]
|
18
31
|
else
|
19
32
|
@series[key_or_index] = Split.new(@proxy, key_or_index)
|
@@ -21,6 +34,8 @@ module Musa
|
|
21
34
|
end
|
22
35
|
|
23
36
|
def each
|
37
|
+
raise "Can't iterate because Splitter is a prototype. To iterate you need a Splitter instance." unless @is_instance
|
38
|
+
|
24
39
|
if block_given?
|
25
40
|
if @proxy.hash_mode?
|
26
41
|
@proxy.components.each do |key|
|
@@ -60,24 +75,24 @@ module Musa
|
|
60
75
|
end
|
61
76
|
end
|
62
77
|
|
63
|
-
class
|
64
|
-
include Series::Serie::Prototyping
|
65
|
-
|
78
|
+
class SplitterProxy
|
66
79
|
def initialize(hash_or_array_serie)
|
67
80
|
@source = hash_or_array_serie
|
68
|
-
|
69
|
-
|
70
|
-
init
|
81
|
+
infer_components
|
71
82
|
end
|
72
83
|
|
73
|
-
attr_reader :
|
84
|
+
attr_reader :source
|
85
|
+
|
86
|
+
def source=(hash_or_array_serie)
|
87
|
+
@source = hash_or_array_serie
|
88
|
+
infer_components
|
89
|
+
end
|
74
90
|
|
75
91
|
def hash_mode?; @hash_mode; end
|
92
|
+
|
76
93
|
def array_mode?; @array_mode; end
|
77
94
|
|
78
|
-
|
79
|
-
infer_components
|
80
|
-
end
|
95
|
+
attr_reader :components
|
81
96
|
|
82
97
|
def restart(key_or_index = nil)
|
83
98
|
if key_or_index
|
@@ -151,18 +166,18 @@ module Musa
|
|
151
166
|
include Series::Serie.base
|
152
167
|
|
153
168
|
def initialize(proxy, key_or_index)
|
154
|
-
@
|
169
|
+
@proxy = proxy
|
155
170
|
@key_or_index = key_or_index
|
156
171
|
|
157
|
-
|
172
|
+
mark_as_instance!
|
158
173
|
end
|
159
174
|
|
160
175
|
private def _restart
|
161
|
-
@
|
176
|
+
@proxy.restart(@key_or_index)
|
162
177
|
end
|
163
178
|
|
164
179
|
private def _next_value
|
165
|
-
@
|
180
|
+
@proxy.next_value(@key_or_index)
|
166
181
|
end
|
167
182
|
end
|
168
183
|
|
@@ -116,6 +116,10 @@ module Musa
|
|
116
116
|
Anticipate.new self, &block
|
117
117
|
end
|
118
118
|
|
119
|
+
def lazy(&block)
|
120
|
+
LazySerieEval.new self, &block
|
121
|
+
end
|
122
|
+
|
119
123
|
###
|
120
124
|
### Implementation
|
121
125
|
###
|
@@ -1006,6 +1010,45 @@ module Musa
|
|
1006
1010
|
end
|
1007
1011
|
|
1008
1012
|
private_constant :HashFromSeriesArray
|
1013
|
+
|
1014
|
+
class LazySerieEval
|
1015
|
+
include Serie.with(source: true, block: true)
|
1016
|
+
|
1017
|
+
def initialize(serie, &block)
|
1018
|
+
self.source = serie
|
1019
|
+
self.proc = block
|
1020
|
+
|
1021
|
+
init
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
def source=(serie)
|
1025
|
+
super
|
1026
|
+
@processed = nil
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
def proc(&block)
|
1030
|
+
super
|
1031
|
+
@processed = nil if block
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
def proc=(block)
|
1035
|
+
super
|
1036
|
+
@processed = nil if block
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
private def _restart
|
1040
|
+
@processed = nil
|
1041
|
+
@source.restart
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
private def _next_value
|
1045
|
+
@processed ||= @block.call(@source)
|
1046
|
+
@processed.next_value
|
1047
|
+
end
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
private_constant :LazySerieEval
|
1009
1051
|
end
|
1052
|
+
|
1010
1053
|
end
|
1011
1054
|
end
|
@@ -7,10 +7,10 @@ module Musa
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class ProxySerie
|
10
|
-
include Series::Serie.with(source: true)
|
10
|
+
include Series::Serie.with(source: true, source_as: :proxy_source)
|
11
11
|
|
12
12
|
def initialize(serie)
|
13
|
-
self.
|
13
|
+
self.proxy_source = serie
|
14
14
|
init
|
15
15
|
end
|
16
16
|
|
@@ -27,15 +27,19 @@ module Musa
|
|
27
27
|
end
|
28
28
|
|
29
29
|
private def method_missing(method_name, *args, **key_args, &block)
|
30
|
-
if @source
|
31
|
-
@source.
|
30
|
+
if @source
|
31
|
+
if @source.respond_to?(method_name)
|
32
|
+
@source.send method_name, *args, **key_args, &block
|
33
|
+
else
|
34
|
+
raise NoMethodError, "undefined method '#{method_name}' for proxied #{@source.to_s}"
|
35
|
+
end
|
32
36
|
else
|
33
37
|
super
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
37
41
|
private def respond_to_missing?(method_name, include_private)
|
38
|
-
@source && @source.respond_to?(method_name, include_private) # || super
|
42
|
+
@source && @source.respond_to?(method_name, include_private) # || super ??
|
39
43
|
end
|
40
44
|
end
|
41
45
|
end
|
@@ -4,38 +4,73 @@ require_relative '../core-ext/with'
|
|
4
4
|
|
5
5
|
module Musa
|
6
6
|
module Series
|
7
|
+
module Operations
|
8
|
+
def composer(&block)
|
9
|
+
Composer::Composer.new(input: self, &block).output
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
module Composer
|
8
14
|
class Composer
|
9
15
|
using Musa::Extension::Arrayfy
|
10
16
|
|
11
|
-
|
17
|
+
def initialize(input: nil, inputs: [:input], outputs: [:output], auto_commit: nil, &block)
|
18
|
+
auto_commit = true if auto_commit.nil?
|
19
|
+
|
20
|
+
inputs = case inputs
|
21
|
+
when Array
|
22
|
+
inputs.collect { |_| [_, nil] }.to_h
|
23
|
+
when nil
|
24
|
+
{}
|
25
|
+
when Hash
|
26
|
+
inputs
|
27
|
+
else
|
28
|
+
raise ArgumentError, "inputs: expected a Hash with input names and source series { name: serie, ... } or an Array with names [name, ...] but received #{inputs}"
|
29
|
+
end
|
30
|
+
|
31
|
+
inputs[:input] = input if input
|
12
32
|
|
13
|
-
def initialize(inputs: [:input], outputs: [:output], &block)
|
14
33
|
@pipelines = {}
|
15
34
|
|
16
|
-
@
|
17
|
-
|
18
|
-
|
35
|
+
def @pipelines.[]=(name, pipeline)
|
36
|
+
pipeline_to_add = @commited ? pipeline.commit! : pipeline
|
37
|
+
super(name, pipeline_to_add)
|
38
|
+
end
|
19
39
|
|
20
|
-
@dsl = DSLContext.new(@pipelines
|
40
|
+
@dsl = DSLContext.new(@pipelines)
|
21
41
|
@inputs = {}
|
22
42
|
@outputs = {}
|
23
43
|
|
24
|
-
inputs&.each do |input|
|
25
|
-
|
26
|
-
|
44
|
+
inputs.keys&.each do |input|
|
45
|
+
p = PROXY()
|
46
|
+
p.proxy_source = inputs[input] if inputs[input]
|
47
|
+
|
48
|
+
@inputs[input] = @pipelines[input] = Pipeline.new(input, input: p, output: p.buffered, pipelines: @pipelines)
|
27
49
|
|
28
50
|
@dsl.define_singleton_method(input) { input }
|
29
51
|
end
|
30
52
|
|
31
53
|
outputs&.each do |output|
|
32
|
-
|
33
|
-
@pipelines[output] =
|
54
|
+
p = PROXY()
|
55
|
+
@outputs[output] = @pipelines[output] = Pipeline.new(output, is_output: true, input: p, output: p, pipelines: @pipelines)
|
34
56
|
|
35
57
|
@dsl.define_singleton_method(output) { output }
|
36
58
|
end
|
37
59
|
|
38
60
|
@dsl.with &block if block
|
61
|
+
commit! if auto_commit
|
62
|
+
end
|
63
|
+
|
64
|
+
def input(name = nil)
|
65
|
+
name ||= :input
|
66
|
+
@inputs[name].input
|
67
|
+
end
|
68
|
+
|
69
|
+
def output(name = nil)
|
70
|
+
raise "Can't access output if the Composer is uncommited. Call '.commit' first." unless @commited
|
71
|
+
|
72
|
+
name ||= :output
|
73
|
+
@outputs[name].output
|
39
74
|
end
|
40
75
|
|
41
76
|
def route(from, to:, on: nil, as: nil)
|
@@ -50,15 +85,76 @@ module Musa
|
|
50
85
|
@dsl.with &block
|
51
86
|
end
|
52
87
|
|
88
|
+
def commit!
|
89
|
+
raise 'Already commited' if @commited
|
90
|
+
|
91
|
+
@outputs.each_value do |pipeline|
|
92
|
+
pipeline.commit!
|
93
|
+
end
|
94
|
+
|
95
|
+
@commited = true
|
96
|
+
end
|
97
|
+
|
98
|
+
class Pipeline
|
99
|
+
def initialize(name, is_output: false, input: nil, output: nil, first_proc: nil, chain_proc: nil, pipelines:)
|
100
|
+
@name = name
|
101
|
+
@is_output = is_output
|
102
|
+
@input = input
|
103
|
+
@output = output
|
104
|
+
@first_proc = first_proc
|
105
|
+
@chain_proc = chain_proc
|
106
|
+
@routes = {}
|
107
|
+
@pipelines = pipelines
|
108
|
+
end
|
109
|
+
|
110
|
+
attr_reader :name, :is_output
|
111
|
+
attr_accessor :input, :output, :proc
|
112
|
+
|
113
|
+
def [](on, as)
|
114
|
+
@routes[[on, as]]
|
115
|
+
end
|
116
|
+
|
117
|
+
def []=(on, as, source)
|
118
|
+
@routes[[on, as]] = Route.new(on, as, source)
|
119
|
+
end
|
120
|
+
|
121
|
+
def commit!
|
122
|
+
first_serie_operation = @first_proc&.call(NIL())
|
123
|
+
@input ||= first_serie_operation
|
124
|
+
|
125
|
+
@routes.each_value do |route|
|
126
|
+
route.source.commit!
|
127
|
+
|
128
|
+
if @is_output
|
129
|
+
@input.proxy_source = route.source.output.buffer
|
130
|
+
elsif route.as
|
131
|
+
@input.send(route.on)[route.as] = route.source.output.buffer
|
132
|
+
else
|
133
|
+
@input.send("#{route.on.to_s}=".to_sym, route.source.output.buffer)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
chain_serie_operation = @chain_proc&.call(@input) || @input
|
138
|
+
@output ||= chain_serie_operation.buffered
|
139
|
+
|
140
|
+
self
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Route
|
145
|
+
def initialize(on, as, source)
|
146
|
+
@on = on
|
147
|
+
@as = as
|
148
|
+
@source = source
|
149
|
+
end
|
150
|
+
attr_accessor :on, :as, :source
|
151
|
+
end
|
152
|
+
|
53
153
|
class DSLContext
|
54
154
|
include Musa::Extension::With
|
55
155
|
|
56
|
-
def initialize(pipelines
|
156
|
+
def initialize(pipelines)
|
57
157
|
@pipelines = pipelines
|
58
|
-
|
59
|
-
@links = links
|
60
|
-
@links_from = links_from
|
61
|
-
@links_to = links_to
|
62
158
|
end
|
63
159
|
|
64
160
|
def route(from, to:, on: nil, as: nil)
|
@@ -68,69 +164,159 @@ module Musa
|
|
68
164
|
raise ArgumentError, "Pipeline '#{from}' not found." unless from_pipeline
|
69
165
|
raise ArgumentError, "Pipeline '#{to}' not found." unless to_pipeline
|
70
166
|
|
71
|
-
|
167
|
+
if to_pipeline.is_output && (on || as)
|
168
|
+
raise ArgumentError, "Output pipeline #{to_pipeline.name} only allows default routing"
|
169
|
+
end
|
72
170
|
|
73
|
-
on ||= as ? :sources : :source
|
171
|
+
on ||= (as ? :sources : :source)
|
74
172
|
|
75
|
-
raise ArgumentError,
|
173
|
+
raise ArgumentError,
|
174
|
+
"Source of pipeline #{to} on #{on} as #{as} already connected to #{to_pipeline[on, as].source.name}" \
|
175
|
+
unless to_pipeline[on, as].nil?
|
76
176
|
|
77
|
-
if as
|
78
|
-
to_pipeline[:input].send(on)[as] = from_pipeline[:output].buffer
|
79
|
-
else
|
80
|
-
to_pipeline[:input].send("#{on.to_s}=".to_sym, from_pipeline[:output].buffer)
|
81
|
-
end
|
82
177
|
|
83
|
-
|
84
|
-
@links_to[[to, on, as]] = from
|
85
|
-
@links << [from, to, on, as]
|
178
|
+
to_pipeline[on, as] = from_pipeline
|
86
179
|
end
|
87
180
|
|
88
181
|
def pipeline(name, elements)
|
89
|
-
first
|
182
|
+
first, chain = parse(elements)
|
183
|
+
@pipelines[name] = Pipeline.new(name, first_proc: first, chain_proc: chain, pipelines: @pipelines)
|
90
184
|
|
91
|
-
|
92
|
-
|
93
|
-
when Hash
|
94
|
-
if e.size == 1
|
95
|
-
operation = e.keys.first
|
96
|
-
parameters = e.values.first
|
185
|
+
define_singleton_method(name) { name }
|
186
|
+
end
|
97
187
|
|
98
|
-
|
99
|
-
|
188
|
+
private def parse(thing)
|
189
|
+
case thing
|
190
|
+
when Array
|
191
|
+
first = chain = nil
|
192
|
+
|
193
|
+
thing.each do |element|
|
194
|
+
case element
|
195
|
+
when Hash
|
196
|
+
new_chain = parse(element)
|
197
|
+
when Symbol
|
198
|
+
new_chain = operation_as_chained_proc(element, nil)
|
199
|
+
when Proc
|
200
|
+
new_chain = operation_as_chained_proc(:map, element)
|
201
|
+
else
|
202
|
+
raise ArgumentError, "Syntax error: don't know how to handle #{element}"
|
203
|
+
end
|
100
204
|
|
101
|
-
|
205
|
+
if first.nil?
|
206
|
+
first = new_chain unless first
|
207
|
+
else
|
208
|
+
chain = chain ? chain >> new_chain : new_chain
|
209
|
+
end
|
210
|
+
end
|
102
211
|
|
103
|
-
|
104
|
-
first = last = Musa::Series::Constructors.PROXY if last.nil?
|
105
|
-
last = last.send(operation, *parameters)
|
212
|
+
[first, chain]
|
106
213
|
|
107
|
-
|
214
|
+
when Hash
|
215
|
+
if thing.size == 1
|
216
|
+
operation = thing.first[0] # key
|
217
|
+
parameter = thing.first[1] # value
|
218
|
+
|
219
|
+
if is_a_series_constructor?(operation)
|
220
|
+
operation_as_chained_proc(operation, parameter)
|
108
221
|
else
|
109
|
-
|
222
|
+
operation_as_chained_proc(operation, parse(parameter))
|
110
223
|
end
|
111
|
-
|
112
|
-
|
113
|
-
# operation == e
|
114
|
-
last = last.send(e) if Musa::Series::Operations.instance_methods.include?(e)
|
224
|
+
else
|
225
|
+
raise ArgumentError, "Syntax error: don't know how to handle #{element}"
|
115
226
|
end
|
116
227
|
|
117
|
-
|
228
|
+
when Symbol
|
229
|
+
operation_as_chained_proc(operation)
|
230
|
+
|
231
|
+
when Proc
|
232
|
+
thing
|
233
|
+
|
234
|
+
else
|
235
|
+
thing
|
118
236
|
end
|
237
|
+
end
|
119
238
|
|
120
|
-
|
239
|
+
private def operation_as_chained_proc(operation, parameter = nil)
|
240
|
+
if is_a_series_constructor?(operation)
|
241
|
+
proc do |last|
|
242
|
+
call_constructor_according_to_last_and_parameter(last, operation, parameter)
|
243
|
+
end
|
121
244
|
|
122
|
-
|
245
|
+
elsif is_a_series_operation?(operation)
|
246
|
+
proc { |last| call_operation_according_to_parameter(last, operation, parameter) }
|
247
|
+
|
248
|
+
else
|
249
|
+
# non-series operation
|
250
|
+
proc { |last| call_operation_according_to_parameter(last, operation, parameter) }
|
251
|
+
end
|
123
252
|
end
|
124
253
|
|
125
|
-
private def
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
254
|
+
private def call_constructor_according_to_last_and_parameter(last, constructor, parameter)
|
255
|
+
case last
|
256
|
+
when Proc
|
257
|
+
call_constructor_according_to_last_and_parameter(last.call, constructor, parameter)
|
258
|
+
|
259
|
+
when Serie
|
260
|
+
# TODO: ignoring last, should make an error?
|
261
|
+
Musa::Series::Constructors.method(constructor).call(*parameter)
|
262
|
+
|
263
|
+
when nil
|
264
|
+
Musa::Series::Constructors.method(constructor).call(*parameter)
|
265
|
+
|
266
|
+
when Array
|
267
|
+
raise "Unexpected parameter #{parameter} for constructor #{constructor} " \
|
268
|
+
"because the previous operation on the pipeline chain returned non-nil #{last}" \
|
269
|
+
unless parameter.nil?
|
270
|
+
|
271
|
+
Musa::Series::Constructors.method(constructor).call(*last)
|
272
|
+
|
273
|
+
when Hash
|
274
|
+
raise "Unexpected parameter #{parameter} for constructor #{constructor} " \
|
275
|
+
"because the previous operation on the pipeline chain returned non-nil #{last}" \
|
276
|
+
unless parameter.nil?
|
277
|
+
|
278
|
+
Musa::Series::Constructors.method(constructor).call(**last)
|
279
|
+
|
280
|
+
else
|
281
|
+
raise ArgumentError, "Don't know how to handle last #{last}"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
private def call_operation_according_to_parameter(target, operation, parameter)
|
286
|
+
case parameter
|
287
|
+
when nil
|
288
|
+
target.send(operation)
|
289
|
+
when Symbol
|
290
|
+
target.send(operation).send(parameter)
|
291
|
+
when Proc
|
292
|
+
target.send(operation, ¶meter)
|
293
|
+
when Array
|
294
|
+
unless parameter.size == 2 && parameter.all? { |_| _.is_a?(Proc) }
|
295
|
+
raise ArgumentError, "Don't know how to handle parameter #{parameter}"
|
296
|
+
end
|
297
|
+
|
298
|
+
target.send(operation, &(parameter.first >> parameter.last))
|
130
299
|
else
|
131
|
-
|
300
|
+
target.send(operation, parameter)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
private def is_a_series_constructor?(operation)
|
305
|
+
Musa::Series::Constructors.instance_methods.include?(operation)
|
306
|
+
end
|
132
307
|
|
308
|
+
private def is_a_series_operation?(operation)
|
309
|
+
Musa::Series::Operations.instance_methods.include?(operation)
|
310
|
+
end
|
311
|
+
|
312
|
+
private def method_missing(symbol, *args, &block)
|
313
|
+
if is_a_series_constructor?(symbol) || is_a_series_operation?(symbol)
|
314
|
+
symbol
|
315
|
+
elsif args.any? || block
|
316
|
+
args += [block] if block
|
133
317
|
pipeline(symbol, args)
|
318
|
+
else # for non-series methods
|
319
|
+
symbol
|
134
320
|
end
|
135
321
|
end
|
136
322
|
|
@@ -142,6 +328,8 @@ module Musa
|
|
142
328
|
end
|
143
329
|
end
|
144
330
|
|
331
|
+
private_constant :Pipeline
|
332
|
+
private_constant :Route
|
145
333
|
private_constant :DSLContext
|
146
334
|
end
|
147
335
|
end
|
data/musa-dsl.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'musa-dsl'
|
3
|
-
s.version = '0.23.
|
4
|
-
s.date = '2021-07-
|
3
|
+
s.version = '0.23.6'
|
4
|
+
s.date = '2021-07-29'
|
5
5
|
s.summary = 'A simple Ruby DSL for making complex music'
|
6
6
|
s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
|
7
7
|
s.authors = ['Javier Sánchez Yeste']
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: musa-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Sánchez Yeste
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: citrus
|