alda-rb 0.2.1 → 0.3.1
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/.github/workflows/main.yml +18 -0
- data/.gitignore +2 -2
- data/CHANGELOG.md +296 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +56 -0
- data/README.md +58 -7
- data/Rakefile +2 -2
- data/alda-rb.gemspec +30 -25
- 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 +32 -0
- data/lib/alda-rb/commandline.rb +176 -33
- data/lib/alda-rb/error.rb +93 -9
- data/lib/alda-rb/event.rb +441 -49
- data/lib/alda-rb/event_list.rb +57 -10
- data/lib/alda-rb/patches.rb +88 -14
- data/lib/alda-rb/repl.rb +330 -61
- data/lib/alda-rb/utils.rb +47 -0
- data/lib/alda-rb/version.rb +1 -1
- data/lib/alda-rb.rb +1 -0
- metadata +74 -8
@@ -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,32 @@
|
|
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
|
+
NO_RELINE = 'Whether to use Reline to read input'.freeze
|
12
|
+
|
13
|
+
host = 'localhost'
|
14
|
+
port = -1
|
15
|
+
color = true
|
16
|
+
preview = true
|
17
|
+
reline = true
|
18
|
+
|
19
|
+
OptionParser.new do |opts|
|
20
|
+
opts.banner = 'Usage: alda-irb [options]'
|
21
|
+
opts.on('-h', '--help', HELP) { exit unless puts opts }
|
22
|
+
opts.on('-H', '--host string', HOST) { host = _1 }
|
23
|
+
opts.on('-p', '--port int', PORT) { port = _1 }
|
24
|
+
opts.on('-c', '--no-color', NO_COLOR) { color = false }
|
25
|
+
opts.on('-P', '--no-preview', NO_PREVIEW) { preview = false }
|
26
|
+
opts.on('-r', '--no-reline', NO_RELINE) { reline = false }
|
27
|
+
end.parse!
|
28
|
+
|
29
|
+
Alda.deduce_generation
|
30
|
+
opts = { color: color, preview: preview, reline: reline }
|
31
|
+
opts.merge! host: host, port: port unless Alda.v1?
|
32
|
+
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,45 @@ 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
|
-
|
55
|
-
|
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
|
+
result = Alda.pipe command, *args, **opts, &:read
|
94
|
+
raise CommandLineError.new $?, result if $?.exitstatus.nonzero?
|
95
|
+
result
|
96
|
+
end.tap { module_function _1 }
|
70
97
|
end
|
71
98
|
|
72
99
|
class << self
|
@@ -84,6 +111,19 @@ module Alda
|
|
84
111
|
# Clear it using ::clear_options.
|
85
112
|
attr_reader :options
|
86
113
|
|
114
|
+
##
|
115
|
+
# The major version of the +alda+ command used.
|
116
|
+
# Possible values: +:v1+ or +:v2+ (i.e. one of the values in Alda::GENERATIONS).
|
117
|
+
# If you try to specify it to values other than those, an ArgumentError will be raised.
|
118
|
+
# This affects several things due to some incompatible changes from \Alda 1 to \Alda 2.
|
119
|
+
# You may use ::deduce_generation to automatically set it,
|
120
|
+
# or use #v1! or #v2! to set it in a shorter way.
|
121
|
+
attr_accessor :generation
|
122
|
+
def generation= gen # :nodoc:
|
123
|
+
raise ArgumentError, "bad generation: #{gen}" unless GENERATIONS.include? gen
|
124
|
+
@generation = gen
|
125
|
+
end
|
126
|
+
|
87
127
|
##
|
88
128
|
# :call-seq:
|
89
129
|
# Alda[**opts] -> self
|
@@ -91,6 +131,7 @@ module Alda
|
|
91
131
|
# Sets the options of alda command.
|
92
132
|
# Not the subcommand options.
|
93
133
|
#
|
134
|
+
# # This example only works for Alda 1.
|
94
135
|
# Alda[port: 1108].up # => "[1108] ..."
|
95
136
|
# Alda.status # => "[1108] ..."
|
96
137
|
#
|
@@ -115,14 +156,104 @@ module Alda
|
|
115
156
|
|
116
157
|
@executable = 'alda'
|
117
158
|
@options = {}
|
159
|
+
@env = {
|
160
|
+
'ALDA_DISABLE_SPAWNING' => 'yes',
|
161
|
+
'ALDA_DISABLE_TELEMETRY' => 'yes'
|
162
|
+
}
|
163
|
+
v2!
|
164
|
+
|
165
|
+
##
|
166
|
+
# :call-seq:
|
167
|
+
# env() -> Hash
|
168
|
+
# env(hash) -> Hash
|
169
|
+
# env(hash) { ... } -> Object
|
170
|
+
#
|
171
|
+
# When called with no arguments,
|
172
|
+
# returns the commandline environment variables (a Hash)
|
173
|
+
# used when running +alda+ on command line.
|
174
|
+
# It is <tt>{"ALDA_DISABLE_SPAWNING"=>"yes","ALDA_DISABLE_TELEMETRY"=>"yes"}</tt> by default
|
175
|
+
# (for speeding up the command line responses:
|
176
|
+
# {alda-lang/alda#368}[https://github.com/alda-lang/alda/issues/368]).
|
177
|
+
#
|
178
|
+
# When called with an argument +hash+,
|
179
|
+
# merge the old environment variables with +hash+ and set
|
180
|
+
# the merged Hash as the new environment variables.
|
181
|
+
# Returns the new environment variables (a Hash).
|
182
|
+
#
|
183
|
+
# When called with an argument +hash+ and a block,
|
184
|
+
# execute the block with the environment being set to the merge of the old environment
|
185
|
+
# and +hash+, and then restore the old environment.
|
186
|
+
# Returns the returned value of the block.
|
187
|
+
def env hash = nil, &block
|
188
|
+
if hash
|
189
|
+
@env = (old_env = @env).merge hash.map { |k, v| [k.to_s, v.to_s] }.to_h
|
190
|
+
block ? block.().tap { @env = old_env } : @env
|
191
|
+
else
|
192
|
+
@env
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# :call-seq:
|
198
|
+
# pipe(command, *args, **opts) -> IO
|
199
|
+
# pipe(command, *args, **opts) { |io| ... } -> Object
|
200
|
+
#
|
201
|
+
# Runs +alda+ in command line as a child process and returns the pipe IO
|
202
|
+
# or pass the IO to the block.
|
203
|
+
# See COMMANDS_FOR_VERSIONS for an explanation of +args+ and +opts+.
|
204
|
+
def pipe command, *args, **opts, &block
|
205
|
+
add_option = ->((key, val)) do
|
206
|
+
next unless val
|
207
|
+
args.push "--#{Alda::Utils.snake_to_slug key}"
|
208
|
+
args.push val.to_s unless val == true
|
209
|
+
end
|
210
|
+
# executable
|
211
|
+
args.unshift Alda.executable
|
212
|
+
args.map! &:to_s
|
213
|
+
# options
|
214
|
+
Alda.options.each &add_option
|
215
|
+
# subcommand
|
216
|
+
args.push command.to_s
|
217
|
+
# subcommand options
|
218
|
+
opts.each &add_option
|
219
|
+
# subprocess
|
220
|
+
spawn_options = Alda::Utils.win_platform? ? { new_pgroup: true } : { pgroup: true }
|
221
|
+
IO.popen Alda.env, args, **spawn_options, &block
|
222
|
+
end
|
223
|
+
|
224
|
+
##
|
225
|
+
# :call-seq:
|
226
|
+
# processes() -> Array
|
227
|
+
#
|
228
|
+
# Returns a Array of details about running \Alda processes.
|
229
|
+
# Only available for \Alda 2.
|
230
|
+
# Each element in the Array is a Hash,
|
231
|
+
# and each Hash has the following keys:
|
232
|
+
# - +:id+: the player-id of the process, a three-letter String.
|
233
|
+
# - +:port+: the port number of the process, an Integer.
|
234
|
+
# - +:state+: the state of the process, a Symbol (may be +nil+, +:ready+, +:active+, or +:starting+).
|
235
|
+
# - +:expiry+: a human-readable description of expiry time of the process, a String (may be +nil+).
|
236
|
+
# - +:type+: the type of the process, a Symbol (may be +:player+ or +:repl_server+).
|
237
|
+
def processes
|
238
|
+
raise GenerationError.new [:v2] if v1?
|
239
|
+
Alda.ps.lines(chomp: true)[1..].map do |line|
|
240
|
+
id, port, state, expiry, type = line.split ?\t
|
241
|
+
port = port.to_i
|
242
|
+
state = state == ?- ? nil : state.to_sym
|
243
|
+
expiry = nil if expiry == ?-
|
244
|
+
type = Alda::Utils.slug_to_snake type
|
245
|
+
{ id: id, port: port, state: state, expiry: expiry, type: type }
|
246
|
+
end
|
247
|
+
end
|
118
248
|
|
119
249
|
##
|
120
250
|
# :call-seq:
|
121
251
|
# up?() -> true or false
|
122
252
|
#
|
123
253
|
# Whether the alda server is up.
|
254
|
+
# Checks whether there are any play processes in ::processes in \Alda 2.
|
124
255
|
def up?
|
125
|
-
status.include?
|
256
|
+
Alda.v1? ? Alda.status.include?('up') : Alda.processes.any? { _1[:type] == :player }
|
126
257
|
end
|
127
258
|
|
128
259
|
##
|
@@ -130,10 +261,22 @@ module Alda
|
|
130
261
|
# down? -> true or false
|
131
262
|
#
|
132
263
|
# Whether the alda server is down.
|
264
|
+
# Checks whether there are no play processes in ::processes in \Alda 2.
|
133
265
|
def down?
|
134
|
-
status.include?
|
266
|
+
Alda.v1? ? Alda.status.include?('down') : Alda.processes.none? { _1[:type] == :player }
|
267
|
+
end
|
268
|
+
|
269
|
+
##
|
270
|
+
# :call-seq:
|
271
|
+
# deduce_generation -> one of Alda::GENERATIONS
|
272
|
+
#
|
273
|
+
# Deduce the generation of \Alda being used by running <tt>alda version</tt> in command line,
|
274
|
+
# and then set ::generation accordingly.
|
275
|
+
def deduce_generation
|
276
|
+
/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/ =~ Alda.version
|
277
|
+
@generation = major == '1' ? :v1 : :v2
|
135
278
|
end
|
136
279
|
|
137
|
-
module_function :up?, :down?,
|
280
|
+
module_function :env, :pipe, :processes, :up?, :down?, :deduce_generation
|
138
281
|
|
139
282
|
end
|
data/lib/alda-rb/error.rb
CHANGED
@@ -9,33 +9,116 @@ 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
|
+
# The status returned by the nREPL server.
|
63
|
+
# It is an Array of Symbol.
|
64
|
+
# Symbols must appear are +:done+, +:error+, and there may be +:unknown_op+.
|
65
|
+
attr_reader :status
|
66
|
+
|
67
|
+
##
|
68
|
+
# :call-seq:
|
69
|
+
# new(host, port, problems, status) -> Alda::NREPLServerError
|
70
|
+
#
|
71
|
+
# Creates a Alda::NREPLServerError object.
|
72
|
+
# Raises Alda::GenerationError if the current generation is not \Alda 2.
|
73
|
+
def initialize host, port, problems, status
|
74
|
+
Alda::GenerationError.assert_generation [:v2]
|
75
|
+
@status = status.map { Alda::Utils.slug_to_snake _1 }
|
76
|
+
if @status.include? :unknown_op
|
77
|
+
super 'unknown operation'
|
78
|
+
else
|
79
|
+
super problems.join ?\n
|
80
|
+
end
|
81
|
+
@host = host
|
82
|
+
@port = port
|
83
|
+
@problems = problems
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# This error is raised when one tries to run commands that are not available for the generation
|
89
|
+
# of \Alda specified by Alda::generation.
|
90
|
+
#
|
91
|
+
# Alda.v1!
|
92
|
+
# Alda.import # (GenerationError)
|
93
|
+
class Alda::GenerationError < StandardError
|
94
|
+
|
95
|
+
##
|
96
|
+
# The actual generation that was set by Alda::generation when the error occurs.
|
97
|
+
attr_reader :generation
|
98
|
+
|
99
|
+
##
|
100
|
+
# The generations that could have been set to avoid the error.
|
101
|
+
# An Array.
|
102
|
+
attr_reader :fine_generations
|
103
|
+
|
104
|
+
##
|
105
|
+
# :call-seq:
|
106
|
+
# new(fine_generations) -> Alda::GenerationError
|
107
|
+
#
|
108
|
+
# Creates a Alda::GenerationError object.
|
109
|
+
def initialize fine_generations
|
110
|
+
super "bad Alda generation for this action; good ones are #{fine_generations}"
|
111
|
+
@generation = Alda.generation
|
112
|
+
@fine_generations = fine_generations
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Raises an Alda::GenerationError if the current generation is not in +fine_generations+.
|
117
|
+
def self.assert_generation fine_generations
|
118
|
+
raise new fine_generations unless fine_generations.include? Alda.generation
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
39
122
|
##
|
40
123
|
# This error is raised when one tries to
|
41
124
|
# append events in an Alda::EventList in a wrong order.
|
@@ -49,8 +132,7 @@ class Alda::OrderError < StandardError
|
|
49
132
|
|
50
133
|
##
|
51
134
|
# The expected element gotten if it is of the correct order.
|
52
|
-
#
|
53
|
-
# See #got
|
135
|
+
# See #got.
|
54
136
|
#
|
55
137
|
# Alda::Score.new do
|
56
138
|
# motif = f4 f e e d d c2
|
@@ -72,6 +154,8 @@ class Alda::OrderError < StandardError
|
|
72
154
|
##
|
73
155
|
# :call-seq:
|
74
156
|
# new(expected, got) -> Alda::OrderError
|
157
|
+
#
|
158
|
+
# Creates a Alda::OrderError object.
|
75
159
|
def initialize expected, got
|
76
160
|
super 'events are out of order'
|
77
161
|
@expected = expected
|