Module: Alda

Included in:
REPL::TempScore
Defined in:
lib/alda-rb/version.rb,
lib/alda-rb/commandline.rb

Overview

The module serving as a namespace.

Defined Under Namespace

Modules: EventList, Utils Classes: AtMarker, Chord, CommandLineError, Cram, Event, EventContainer, GenerationError, GetVariable, InlineLisp, LispIdentifier, Marker, NREPLServerError, Note, Octave, OrderError, Part, REPL, Raw, Rest, Score, Sequence, SetVariable, Voice

Constant Summary collapse

VERSION =

The version number of alda-rb.

The same as that in alda-rb gem spec.

'0.3.1'
GENERATIONS =

The Array of possible values of ::generation. It is just the array [:v1, :v2]

You can use :v1? and :v2? to get whether the current generation is :v1 or :v2. For example, Alda.v1? is the same as Alda.generation == :v1. You can also use :v1! and :v2! to set the generation to :v1 or :v2. For example, Alda.v1! is the same as Alda.generation = :v1.

%i[v1 v2].freeze
COMMANDS_FOR_VERSIONS =

The available subcommands of alda executable. This is a Hash, with keys being possible values of ::generation, and values being an Array of symbols of the available commands of that generation.

Alda is able to invoke alda at the command line. The subcommand is the name of the method invoked upon Alda.

The keyword arguments are interpreted as the subcommand options. To specify the command options, use ::[].

The return value is the string output by the command in STDOUT.

If the exit code is nonzero, an Alda::CommandLineError is raised.

Alda.version
# => "Client version: 1.4.0\nServer version: [27713] 1.4.0\n"
Alda.parse code: 'bassoon: o3 c'
# => "{\"chord-mode\":false,\"current-instruments\":...}\n"

The available commands are:

  • If ::generation is :v1: help, update, repl, up, start_server, init, down, stop_server, downup, restart_server, list, status, version, play, stop, parse, instruments, and export.

  • If ::generation is :v2: doctor, export, help, import, instruments, parse, play, ps, repl, shutdown, stop, telemetry, update, and version.

Trying to run a command that is not support by the current generation set by ::generation will raise an Alda::GenerationError.

{
	v1: %i[
		help update repl up start_server init down stop_server
		downup restart_server list status version play stop parse
		instruments export
	].freeze,
	v2: %i[
		doctor export help import instruments parse play ps repl shutdown stop
		telemetry update version
	].freeze
}.freeze
COMMANDS =

The Hash of available commands. The symbols of commands are keys and each value is an Array of generations where the command is available.

COMMANDS_FOR_VERSIONS.each_with_object({}) do |(gen, commands), r|
	commands.each { (r[_1] ||= []).push gen }
end.freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.executableObject

The path to the alda executable.

The default value is "alda", which will depend on your PATH.



106
107
108
# File 'lib/alda-rb/commandline.rb', line 106

def executable
  @executable
end

.generationObject

The major version of the alda command used. Possible values: :v1 or :v2 (i.e. one of the values in Alda::GENERATIONS). If you try to specify it to values other than those, an ArgumentError will be raised. This affects several things due to some incompatible changes from Alda 1 to Alda 2. You may use ::deduce_generation to automatically set it, or use #v1! or #v2! to set it in a shorter way.



121
122
123
# File 'lib/alda-rb/commandline.rb', line 121

def generation
  @generation
end

.optionsObject (readonly)

The commandline options set using ::[]. Not the subcommand options. Clear it using ::clear_options.



112
113
114
# File 'lib/alda-rb/commandline.rb', line 112

def options
  @options
end

Class Method Details

.[](**opts) ⇒ Object

:call-seq:

Alda[**opts] -> self

Sets the options of alda command. Not the subcommand options.

# This example only works for Alda 1.
Alda[port: 1108].up # => "[1108] ..."
Alda.status # => "[1108] ..."

Further set options will be merged. The options can be seen by ::options. To clear them, use ::clear_options.



141
142
143
144
# File 'lib/alda-rb/commandline.rb', line 141

def [] **opts
	@options.merge! opts
	self
end

.clear_optionsObject

:call-seq:

clear_options() -> nil

Clears the command line options. Makes ::options an empty Array.



152
153
154
# File 'lib/alda-rb/commandline.rb', line 152

def clear_options
	@options.clear
end

.deduce_generationObject

:call-seq:

deduce_generation -> one of Alda::GENERATIONS

Deduce the generation of Alda being used by running alda version in command line, and then set ::generation accordingly.



275
276
277
278
# File 'lib/alda-rb/commandline.rb', line 275

def deduce_generation
	/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/ =~ Alda.version
	@generation = major == '1' ? :v1 : :v2
end

.down?Boolean

:call-seq:

down? -> true or false

Whether the alda server is down. Checks whether there are no play processes in ::processes in Alda 2.

Returns:

  • (Boolean)


265
266
267
# File 'lib/alda-rb/commandline.rb', line 265

def down?
	Alda.v1? ? Alda.status.include?('down') : Alda.processes.none? { _1[:type] == :player }
end

.env(hash = nil, &block) ⇒ Object

:call-seq:

env() -> Hash
env(hash) -> Hash
env(hash) { ... } -> Object

When called with no arguments, returns the commandline environment variables (a Hash) used when running alda on command line. It is {"ALDA_DISABLE_SPAWNING"=>"yes","ALDA_DISABLE_TELEMETRY"=>"yes"} by default (for speeding up the command line responses: alda-lang/aldaalda-lang/alda#368[https://github.com/alda-lang/alda/issues/368]).

When called with an argument hash, merge the old environment variables with hash and set the merged Hash as the new environment variables. Returns the new environment variables (a Hash).

When called with an argument hash and a block, execute the block with the environment being set to the merge of the old environment and hash, and then restore the old environment. Returns the returned value of the block.



187
188
189
190
191
192
193
194
# File 'lib/alda-rb/commandline.rb', line 187

def env hash = nil, &block
	if hash
		@env = (old_env = @env).merge hash.map { |k, v| [k.to_s, v.to_s] }.to_h
		block ? block.().tap { @env = old_env } : @env
	else
		@env
	end
end

.pipe(command, *args, **opts, &block) ⇒ Object

:call-seq:

pipe(command, *args, **opts) -> IO
pipe(command, *args, **opts) { |io| ... } -> Object

Runs alda in command line as a child process and returns the pipe IO or pass the IO to the block. See COMMANDS_FOR_VERSIONS for an explanation of args and opts.



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/alda-rb/commandline.rb', line 204

def pipe command, *args, **opts, &block
	add_option = ->((key, val)) do
		next unless val
		args.push "--#{Alda::Utils.snake_to_slug key}"
		args.push val.to_s unless val == true
	end
	# executable
	args.unshift Alda.executable
	args.map! &:to_s
	# options
	Alda.options.each &add_option
	# subcommand
	args.push command.to_s
	# subcommand options
	opts.each &add_option
	# subprocess
	spawn_options = Alda::Utils.win_platform? ? { new_pgroup: true } : { pgroup: true }
	IO.popen Alda.env, args, **spawn_options, &block
end

.processesObject

:call-seq:

processes() -> Array

Returns a Array of details about running Alda processes. Only available for Alda 2. Each element in the Array is a Hash, and each Hash has the following keys:

  • :id: the player-id of the process, a three-letter String.

  • :port: the port number of the process, an Integer.

  • :state: the state of the process, a Symbol (may be nil, :ready, :active, or :starting).

  • :expiry: a human-readable description of expiry time of the process, a String (may be nil).

  • :type: the type of the process, a Symbol (may be :player or :repl_server).



237
238
239
240
241
242
243
244
245
246
247
# File 'lib/alda-rb/commandline.rb', line 237

def processes
	raise GenerationError.new [:v2] if v1?
	Alda.ps.lines(chomp: true)[1..].map do |line|
		id, port, state, expiry, type = line.split ?\t
		port = port.to_i
		state = state == ?- ? nil : state.to_sym
		expiry = nil if expiry == ?-
		type = Alda::Utils.slug_to_snake type
		{ id: id, port: port, state: state, expiry: expiry, type: type }
	end
end

.up?Boolean

:call-seq:

up?() -> true or false

Whether the alda server is up. Checks whether there are any play processes in ::processes in Alda 2.

Returns:

  • (Boolean)


255
256
257
# File 'lib/alda-rb/commandline.rb', line 255

def up?
	Alda.v1? ? Alda.status.include?('up') : Alda.processes.any? { _1[:type] == :player }
end