alda-rb 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +2 -2
- data/CHANGELOG.md +271 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +54 -0
- data/README.md +56 -7
- data/Rakefile +2 -2
- data/alda-rb.gemspec +3 -3
- data/examples/bwv846_prelude.rb +3 -3
- data/examples/clapping_music.rb +1 -1
- data/examples/dot_accessor.rb +1 -1
- data/examples/dynamics.rb +22 -0
- data/examples/entropy.rb +2 -2
- data/examples/hanon.rb +2 -2
- data/examples/marriage_d_amour.rb +114 -0
- data/examples/multi_poly.rb +2 -2
- data/examples/track-volume.rb +32 -0
- data/examples/variables-2.rb +16 -0
- data/exe/alda-irb +29 -0
- data/lib/alda-rb/commandline.rb +139 -33
- data/lib/alda-rb/error.rb +82 -9
- data/lib/alda-rb/event.rb +441 -49
- data/lib/alda-rb/event_list.rb +54 -7
- data/lib/alda-rb/patches.rb +88 -14
- data/lib/alda-rb/repl.rb +311 -59
- data/lib/alda-rb/utils.rb +47 -0
- data/lib/alda-rb/version.rb +1 -1
- data/lib/alda-rb.rb +1 -0
- metadata +17 -7
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'alda-rb'
|
4
|
+
|
5
|
+
# Marriage D' Amour
|
6
|
+
#
|
7
|
+
# Richard Clayderman
|
8
|
+
# Paul de Senneville
|
9
|
+
#
|
10
|
+
# sheet music:
|
11
|
+
# https://musescore.com/user/153958/scores/154629
|
12
|
+
|
13
|
+
using Alda::Sequence::RefineFlatten
|
14
|
+
|
15
|
+
module Alda::EventList
|
16
|
+
def up8 &block
|
17
|
+
result = block.()
|
18
|
+
result.events = result.events.map do |event|
|
19
|
+
if event.is_event_of? Alda::Octave
|
20
|
+
event
|
21
|
+
else
|
22
|
+
if event.respond_to? :labels
|
23
|
+
labels = event.labels
|
24
|
+
event.labels = []
|
25
|
+
end
|
26
|
+
sequence = Alda::Sequence.new
|
27
|
+
sequence.events = [Alda::Chord.new(
|
28
|
+
event,
|
29
|
+
+Alda::Octave.new(''),
|
30
|
+
event,
|
31
|
+
-Alda::Octave.new('')
|
32
|
+
)]
|
33
|
+
container = Alda::EventContainer.new(sequence, result)
|
34
|
+
container.labels = labels || []
|
35
|
+
container
|
36
|
+
end
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Alda::Score.new do
|
43
|
+
key_sig! 'b- e-'
|
44
|
+
tempo! 80
|
45
|
+
piano_ 'right'
|
46
|
+
piano_ 'left'
|
47
|
+
|
48
|
+
right_
|
49
|
+
r2_4_8_16 o5 g16
|
50
|
+
left_
|
51
|
+
o2 g8 o! d b d b d b d
|
52
|
+
|
53
|
+
motif1 = -> do
|
54
|
+
right_
|
55
|
+
g16 a a b b a a g g d d o? b b g g o! f f e e d e f e4_8
|
56
|
+
left_
|
57
|
+
o2 g o! d b d b d b d e g o! e o? g o! e o? g
|
58
|
+
|
59
|
+
right_
|
60
|
+
v1 r16 e e f f g g a a f f c c e e d d c d e _marker1 d8_4
|
61
|
+
v2 __marker1 r8 o6 d32 o! d8_16_32 v0
|
62
|
+
left_
|
63
|
+
v1 o? f o! c a c a c a o? b o! f o! d o? d8_4
|
64
|
+
v2 __marker1 r8 o4 g4? v0
|
65
|
+
end
|
66
|
+
motif1.()
|
67
|
+
|
68
|
+
motif2 = -> do
|
69
|
+
right_
|
70
|
+
o5 s{ (d8 o? g16 b o! d c)*2; d8 (o? g16 b o! e d e8)*2; e16 d e e_ f8 f16 g f g d4_8 o!}*2
|
71
|
+
left_
|
72
|
+
s{o2 g8 o! d b d b d o? g o! d b c g o! e o? g o! e o? g o? f o! c a o? b
|
73
|
+
(o! b o? up8{s{a}})%1; up8{b a}%2}*2
|
74
|
+
end
|
75
|
+
motif2.()
|
76
|
+
|
77
|
+
motif3 = -> do
|
78
|
+
right_
|
79
|
+
o5 b8_16 d16 d e e8_16 c16 a g a8_16 c16 c d d8 o? b16 b o! g f g8_16 o? b16 b o! c c8_16 o? a16 o! d c d4_8
|
80
|
+
left_
|
81
|
+
up8{s{g}}; o! d b c g o! e o? o? f o! c a o? b o! f o? a g o! d b o? a o! e o! c o? d o? up8{e_ g?}
|
82
|
+
end
|
83
|
+
motif3.()
|
84
|
+
|
85
|
+
tt2 { s{o2 g o! d b c g o! e o? o? f o! c a o? b o! b o? up8{s{a}}; g o! d b c g o! e o? o? f o! c a o? g o! d b}*2 }
|
86
|
+
motif4 = -> do
|
87
|
+
tt1 = -> { (o5 b8_16 b16 b o! c c8_16 o? b16 a g f8_16 f16 g f d4_8%1)*2 }
|
88
|
+
right_
|
89
|
+
tt1.(); g4_8; up8{tt1.()}
|
90
|
+
left_
|
91
|
+
tt2 o4 d g b
|
92
|
+
end
|
93
|
+
motif4.()
|
94
|
+
right_; up8{s{g2_4}}
|
95
|
+
|
96
|
+
motif2.()
|
97
|
+
|
98
|
+
motif4.()
|
99
|
+
right_
|
100
|
+
o5 up8{s{g2_8}}; r16 g16
|
101
|
+
|
102
|
+
motif1.()
|
103
|
+
motif2.()
|
104
|
+
motif3.()
|
105
|
+
|
106
|
+
tt1 = -> { (o5 b8_16 b16 b o! c c8_16 o? b16 a g f8_16 f16 g f d4_8%1)*2 }
|
107
|
+
|
108
|
+
right_
|
109
|
+
tt1.(); g4_8
|
110
|
+
-> { up8{tt1.()}; up8{s{g4_8}} }*2
|
111
|
+
up8{tt1.()}; up8{s{g1}}
|
112
|
+
left_
|
113
|
+
tt2*2; o4 d g o! d g r8_16 o! g4_8
|
114
|
+
end.play
|
data/examples/multi_poly.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'alda-rb'
|
4
|
+
|
5
|
+
Alda::Score.new do
|
6
|
+
tempo! 105
|
7
|
+
|
8
|
+
piano_
|
9
|
+
pmotif do
|
10
|
+
s do
|
11
|
+
o3
|
12
|
+
vol 100; a16
|
13
|
+
vol 90; -b
|
14
|
+
vol 80; a
|
15
|
+
vol 70; -b
|
16
|
+
vol 60; o! c d
|
17
|
+
vol 50; e f
|
18
|
+
end * 2
|
19
|
+
end
|
20
|
+
|
21
|
+
70.step(10, -20) { track_vol _1; pmotif }
|
22
|
+
|
23
|
+
clarinet_
|
24
|
+
cmotif do
|
25
|
+
quant 100; o5
|
26
|
+
vol 60; d8
|
27
|
+
vol 70; c
|
28
|
+
vol 80; o? +f2_4
|
29
|
+
end
|
30
|
+
|
31
|
+
10.step(70, 20) { track_vol _1; cmotif }
|
32
|
+
end.play
|
data/exe/alda-irb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'alda-rb'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
HELP = 'Print this help message and exit'.freeze
|
7
|
+
HOST = 'The hostname of the Alda REPL server; only useful in Alda 2; see `alda repl --help`'.freeze
|
8
|
+
PORT = 'The port of the Alda REPL server; only useful in Alda 2; see `alda repl --help`'.freeze
|
9
|
+
NO_COLOR = 'Whether the output should not be colored'.freeze
|
10
|
+
NO_PREVIEW = 'Whether a preview of what Alda code will not be played everytime you input ruby codes'.freeze
|
11
|
+
|
12
|
+
host = 'localhost'
|
13
|
+
port = -1
|
14
|
+
color = true
|
15
|
+
preview = true
|
16
|
+
|
17
|
+
OptionParser.new do |opts|
|
18
|
+
opts.banner = 'Usage: alda-irb [options]'
|
19
|
+
opts.on('-h', '--help', HELP) { exit unless puts opts }
|
20
|
+
opts.on('-H', '--host string', HOST) { host = _1 }
|
21
|
+
opts.on('-p', '--port int', PORT) { port = _1 }
|
22
|
+
opts.on('-c', '--no-color', NO_COLOR) { color = false }
|
23
|
+
opts.on('-P', '--no-preview', NO_PREVIEW) { preview = false }
|
24
|
+
end.parse!
|
25
|
+
|
26
|
+
Alda.deduce_generation
|
27
|
+
opts = {color: color, preview: preview}
|
28
|
+
opts.merge! host: host, port: port unless Alda.v1?
|
29
|
+
Alda::REPL.new(**opts).run
|
data/lib/alda-rb/commandline.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
##
|
2
|
+
# Adding functions that is accessible everywhere.
|
1
3
|
module Kernel
|
2
4
|
##
|
3
5
|
# :call-seq:
|
@@ -19,7 +21,24 @@ end
|
|
19
21
|
module Alda
|
20
22
|
|
21
23
|
##
|
22
|
-
# The
|
24
|
+
# The Array of possible values of ::generation.
|
25
|
+
# It is just the array <tt>[:v1, :v2]</tt>
|
26
|
+
#
|
27
|
+
# You can use +:v1?+ and +:v2?+ to get whether the current generation is +:v1+ or +:v2+.
|
28
|
+
# For example, <tt>Alda.v1?</tt> is the same as <tt>Alda.generation == :v1</tt>.
|
29
|
+
# You can also use +:v1!+ and +:v2!+ to set the generation to +:v1+ or +:v2+.
|
30
|
+
# For example, <tt>Alda.v1!</tt> is the same as <tt>Alda.generation = :v1</tt>.
|
31
|
+
GENERATIONS = %i[v1 v2].freeze
|
32
|
+
|
33
|
+
GENERATIONS.each do |gen|
|
34
|
+
module_function define_method("#{gen}?") { @generation == gen }
|
35
|
+
module_function define_method("#{gen}!") { @generation = gen }
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# The available subcommands of alda executable.
|
40
|
+
# This is a Hash, with keys being possible values of ::generation,
|
41
|
+
# and values being an Array of symbols of the available commands of that generation.
|
23
42
|
#
|
24
43
|
# Alda is able to invoke +alda+ at the command line.
|
25
44
|
# The subcommand is the name of the method invoked upon Alda.
|
@@ -36,37 +55,43 @@ module Alda
|
|
36
55
|
# Alda.parse code: 'bassoon: o3 c'
|
37
56
|
# # => "{\"chord-mode\":false,\"current-instruments\":...}\n"
|
38
57
|
#
|
39
|
-
# The available commands are:
|
40
|
-
#
|
41
|
-
#
|
42
|
-
# +
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
58
|
+
# The available commands are:
|
59
|
+
#
|
60
|
+
# * If ::generation is +:v1+:
|
61
|
+
# +help+, +update+, +repl+, +up+, +start_server+, +init+, +down+, +stop_server+,
|
62
|
+
# +downup+, +restart_server+, +list+, +status+, +version+, +play+, +stop+, +parse+,
|
63
|
+
# +instruments+, and +export+.
|
64
|
+
# * If ::generation is +:v2+:
|
65
|
+
# +doctor+, +export+, +help+, +import+, +instruments+, +parse+, +play+,
|
66
|
+
# +ps+, +repl+, +shutdown+, +stop+, +telemetry+, +update+, and +version+.
|
67
|
+
#
|
68
|
+
# Trying to run a command that is not support by the current generation set by ::generation
|
69
|
+
# will raise an Alda::GenerationError.
|
70
|
+
COMMANDS_FOR_VERSIONS = {
|
71
|
+
v1: %i[
|
72
|
+
help update repl up start_server init down stop_server
|
73
|
+
downup restart_server list status version play stop parse
|
74
|
+
instruments export
|
75
|
+
].freeze,
|
76
|
+
v2: %i[
|
77
|
+
doctor export help import instruments parse play ps repl shutdown stop
|
78
|
+
telemetry update version
|
79
|
+
].freeze
|
80
|
+
}.freeze
|
48
81
|
|
49
|
-
|
82
|
+
##
|
83
|
+
# The Hash of available commands.
|
84
|
+
# The symbols of commands are keys
|
85
|
+
# and each value is an Array of generations where the command is available.
|
86
|
+
COMMANDS = COMMANDS_FOR_VERSIONS.each_with_object({}) do |(gen, commands), r|
|
87
|
+
commands.each { (r[_1] ||= []).push gen }
|
88
|
+
end.freeze
|
89
|
+
|
90
|
+
COMMANDS.each do |command, generations|
|
50
91
|
define_method command do |*args, **opts|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
args.push val.to_s unless val == true
|
55
|
-
end
|
56
|
-
# executable
|
57
|
-
args.unshift Alda.executable
|
58
|
-
args.map! &:to_s
|
59
|
-
# options
|
60
|
-
Alda.options.each &block
|
61
|
-
# subcommand
|
62
|
-
args.push command.to_s
|
63
|
-
# subcommand options
|
64
|
-
opts.each &block
|
65
|
-
# subprocess
|
66
|
-
IO.popen(args, &:read).tap do
|
67
|
-
raise CommandLineError.new $?, _1 if $?.exitstatus.nonzero?
|
68
|
-
end
|
69
|
-
end
|
92
|
+
Alda::GenerationError.assert_generation generations
|
93
|
+
Alda.pipe(command, *args, **opts, &:read).tap { raise CommandLineError.new $?, _1 if $?.exitstatus.nonzero? }
|
94
|
+
end.tap { module_function _1 }
|
70
95
|
end
|
71
96
|
|
72
97
|
class << self
|
@@ -84,6 +109,19 @@ module Alda
|
|
84
109
|
# Clear it using ::clear_options.
|
85
110
|
attr_reader :options
|
86
111
|
|
112
|
+
##
|
113
|
+
# The major version of the +alda+ command used.
|
114
|
+
# Possible values: +:v1+ or +:v2+ (i.e. one of the values in Alda::GENERATIONS).
|
115
|
+
# If you try to specify it to values other than those, an ArgumentError will be raised.
|
116
|
+
# This affects several things due to some incompatible changes from \Alda 1 to \Alda 2.
|
117
|
+
# You may use ::deduce_generation to automatically set it,
|
118
|
+
# or use #v1! or #v2! to set it in a shorter way.
|
119
|
+
attr_accessor :generation
|
120
|
+
def generation= gen # :nodoc:
|
121
|
+
raise ArgumentError, "bad generation: #{gen}" unless GENERATIONS.include? gen
|
122
|
+
@generation = gen
|
123
|
+
end
|
124
|
+
|
87
125
|
##
|
88
126
|
# :call-seq:
|
89
127
|
# Alda[**opts] -> self
|
@@ -91,6 +129,7 @@ module Alda
|
|
91
129
|
# Sets the options of alda command.
|
92
130
|
# Not the subcommand options.
|
93
131
|
#
|
132
|
+
# # This example only works for Alda 1.
|
94
133
|
# Alda[port: 1108].up # => "[1108] ..."
|
95
134
|
# Alda.status # => "[1108] ..."
|
96
135
|
#
|
@@ -115,14 +154,69 @@ module Alda
|
|
115
154
|
|
116
155
|
@executable = 'alda'
|
117
156
|
@options = {}
|
157
|
+
v2!
|
158
|
+
|
159
|
+
##
|
160
|
+
# :call-seq:
|
161
|
+
# pipe(command, *args, **opts) -> IO
|
162
|
+
# pipe(command, *args, **opts) { |io| ... } -> Object
|
163
|
+
#
|
164
|
+
# Runs +alda+ in command line as a child process and returns the pipe IO
|
165
|
+
# or pass the IO to the block.
|
166
|
+
# See COMMANDS_FOR_VERSIONS for an explanation of +args+ and +opts+.
|
167
|
+
def pipe command, *args, **opts, &block
|
168
|
+
add_option = ->key, val do
|
169
|
+
next unless val
|
170
|
+
args.push "--#{Alda::Utils.snake_to_slug key}"
|
171
|
+
args.push val.to_s unless val == true
|
172
|
+
end
|
173
|
+
# executable
|
174
|
+
args.unshift Alda.executable
|
175
|
+
args.map! &:to_s
|
176
|
+
# options
|
177
|
+
Alda.options.each &add_option
|
178
|
+
# subcommand
|
179
|
+
args.push command.to_s
|
180
|
+
# subcommand options
|
181
|
+
opts.each &add_option
|
182
|
+
# subprocess
|
183
|
+
spawn_options = Alda::Utils.win_platform? ? {new_pgroup: true} : {pgroup: true}
|
184
|
+
IO.popen args, **spawn_options, &block
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# :call-seq:
|
189
|
+
# processes() -> Array
|
190
|
+
#
|
191
|
+
# Returns a Array of details about running \Alda processes.
|
192
|
+
# Only available for \Alda 2.
|
193
|
+
# Each element in the Array is a Hash,
|
194
|
+
# and each Hash has the following keys:
|
195
|
+
# - +:id+: the player-id of the process, a three-letter String.
|
196
|
+
# - +:port+: the port number of the process, an Integer.
|
197
|
+
# - +:state+: the state of the process, a Symbol (may be +nil+, +:ready+, +:active+ etc.).
|
198
|
+
# - +:expiry+: a human-readable description of expiry time of the process, a String (may be +nil+).
|
199
|
+
# - +:type+: the type of the process, a Symbol (may be +:player+ or +:repl_server+).
|
200
|
+
def processes
|
201
|
+
raise GenerationError.new [:v2] if v1?
|
202
|
+
Alda.ps.lines(chomp: true)[1..].map do |line|
|
203
|
+
id, port, state, expiry, type = line.split ?\t
|
204
|
+
port = port.to_i
|
205
|
+
state = state == ?- ? nil : state.to_sym
|
206
|
+
expiry = nil if expiry == ?-
|
207
|
+
type = Alda::Utils.slug_to_snake type
|
208
|
+
{id: id, port: port, state: state, expiry: expiry, type: type}
|
209
|
+
end
|
210
|
+
end
|
118
211
|
|
119
212
|
##
|
120
213
|
# :call-seq:
|
121
214
|
# up?() -> true or false
|
122
215
|
#
|
123
216
|
# Whether the alda server is up.
|
217
|
+
# Always returns true if ::generation is +:v2+.
|
124
218
|
def up?
|
125
|
-
status.include?
|
219
|
+
Alda.v2? || Alda.status.include?('up')
|
126
220
|
end
|
127
221
|
|
128
222
|
##
|
@@ -130,10 +224,22 @@ module Alda
|
|
130
224
|
# down? -> true or false
|
131
225
|
#
|
132
226
|
# Whether the alda server is down.
|
227
|
+
# Always returns false if ::generation is +:v2+.
|
133
228
|
def down?
|
134
|
-
status.include?
|
229
|
+
!Alda.v2? && Alda.status.include?('down')
|
230
|
+
end
|
231
|
+
|
232
|
+
##
|
233
|
+
# :call-seq:
|
234
|
+
# deduce_generation -> one of Alda::GENERATIONS
|
235
|
+
#
|
236
|
+
# Deduce the generation of \Alda being used by running <tt>alda version</tt> in command line,
|
237
|
+
# and then set ::generation accordingly.
|
238
|
+
def deduce_generation
|
239
|
+
/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/ =~ Alda.version
|
240
|
+
@generation = major == '1' ? :v1 : :v2
|
135
241
|
end
|
136
242
|
|
137
|
-
module_function :up?, :down?,
|
243
|
+
module_function :pipe, :processes, :up?, :down?, :deduce_generation
|
138
244
|
|
139
245
|
end
|
data/lib/alda-rb/error.rb
CHANGED
@@ -9,33 +9,105 @@ class Alda::CommandLineError < StandardError
|
|
9
9
|
|
10
10
|
##
|
11
11
|
# The port on which the problematic alda server runs.
|
12
|
+
# This is only available for \Alda 1.
|
12
13
|
#
|
13
14
|
# begin
|
14
15
|
# Alda[port: 1108].play code: 'y'
|
15
16
|
# rescue CommandLineError => e
|
16
17
|
# e.port # => 1108
|
17
18
|
# end
|
18
|
-
|
19
|
+
def port
|
20
|
+
Alda::GenerationError.assert_generation [:v1]
|
21
|
+
@port
|
22
|
+
end
|
19
23
|
|
20
24
|
##
|
21
25
|
# :call-seq:
|
22
26
|
# new(status, msg=nil) -> Alda::CommandLineError
|
23
27
|
#
|
24
28
|
# Create a Alda::CommandLineError object.
|
25
|
-
# +status+ is the status of the process running +alda+ command.
|
26
|
-
# +msg+ is output of +alda+ command. port
|
29
|
+
# +status+ is the status of the process running +alda+ command (can be nil).
|
30
|
+
# +msg+ is the output of +alda+ command. #port info is extracted from +msg+ in \Alda 1.
|
27
31
|
def initialize status, msg = nil
|
28
|
-
if
|
29
|
-
super
|
30
|
-
@port =
|
32
|
+
if Alda.v1? && msg && /^\[(?<port>\d+)\]\sERROR\s(?<message>.*)$/ =~ msg
|
33
|
+
super message
|
34
|
+
@port = port.to_i
|
31
35
|
else
|
32
36
|
super msg
|
33
|
-
@port = nil
|
34
37
|
end
|
35
38
|
@status = status
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
42
|
+
##
|
43
|
+
# The error is raised when the \Alda nREPL server returns problems.
|
44
|
+
# This is only available for \Alda 2.
|
45
|
+
# See Alda::REPL#message.
|
46
|
+
class Alda::NREPLServerError < StandardError
|
47
|
+
|
48
|
+
##
|
49
|
+
# The hostname of the nREPL server.
|
50
|
+
attr_reader :host
|
51
|
+
|
52
|
+
##
|
53
|
+
# The port of the nREPL server.
|
54
|
+
attr_reader :port
|
55
|
+
|
56
|
+
##
|
57
|
+
# The problems returned by the nREPL server.
|
58
|
+
# This is an Array of String.
|
59
|
+
attr_reader :problems
|
60
|
+
|
61
|
+
##
|
62
|
+
# :call-seq:
|
63
|
+
# new(host, port, problems) -> Alda::NREPLServerError
|
64
|
+
#
|
65
|
+
# Creates a Alda::NREPLServerError object.
|
66
|
+
# Raises Alda::GenerationError if the current generation is not \Alda 2.
|
67
|
+
def initialize host, port, problems
|
68
|
+
Alda::GenerationError.assert_generation [:v2]
|
69
|
+
super problems.join ?\n
|
70
|
+
@host = host
|
71
|
+
@port = port
|
72
|
+
@problems = problems
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# This error is raised when one tries to run commands that are not available for the generation
|
78
|
+
# of \Alda specified by Alda::generation.
|
79
|
+
#
|
80
|
+
# Alda.v1!
|
81
|
+
# Alda.import # (GenerationError)
|
82
|
+
class Alda::GenerationError < StandardError
|
83
|
+
|
84
|
+
##
|
85
|
+
# The actual generation that was set by Alda::generation when the error occurs.
|
86
|
+
attr_reader :generation
|
87
|
+
|
88
|
+
##
|
89
|
+
# The generations that could have been set to avoid the error.
|
90
|
+
# An Array.
|
91
|
+
attr_reader :fine_generations
|
92
|
+
|
93
|
+
##
|
94
|
+
# :call-seq:
|
95
|
+
# new(fine_generations) -> Alda::GenerationError
|
96
|
+
#
|
97
|
+
# Creates a Alda::GenerationError object.
|
98
|
+
def initialize fine_generations
|
99
|
+
super "bad Alda generation for this action; good ones are #{fine_generations}"
|
100
|
+
@generation = Alda.generation
|
101
|
+
@fine_generations = fine_generations
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Raises an Alda::GenerationError if the current generation is not in +fine_generations+.
|
106
|
+
def self.assert_generation fine_generations
|
107
|
+
raise new fine_generations unless fine_generations.include? Alda.generation
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
39
111
|
##
|
40
112
|
# This error is raised when one tries to
|
41
113
|
# append events in an Alda::EventList in a wrong order.
|
@@ -49,8 +121,7 @@ class Alda::OrderError < StandardError
|
|
49
121
|
|
50
122
|
##
|
51
123
|
# The expected element gotten if it is of the correct order.
|
52
|
-
#
|
53
|
-
# See #got
|
124
|
+
# See #got.
|
54
125
|
#
|
55
126
|
# Alda::Score.new do
|
56
127
|
# motif = f4 f e e d d c2
|
@@ -72,6 +143,8 @@ class Alda::OrderError < StandardError
|
|
72
143
|
##
|
73
144
|
# :call-seq:
|
74
145
|
# new(expected, got) -> Alda::OrderError
|
146
|
+
#
|
147
|
+
# Creates a Alda::OrderError object.
|
75
148
|
def initialize expected, got
|
76
149
|
super 'events are out of order'
|
77
150
|
@expected = expected
|