A.2.3 Variables de entrada y Scheme

El formato de entrada contempla la noción de variables: en el siguiente ejemplo, se asigna una expresión musical a una variable con el nombre traLaLa.

traLaLa = { c'4 d'4 }

También hay una forma de ámbito: en el ejemplo siguiente, el bloque \layout también contiene una variable traLaLa, que es independiente de la \traLaLa externa.

traLaLa = { c'4 d'4 }
\layout { traLaLa = 1.0 }

En efecto, cada archivo de entrada constituye un ámbito, y cada bloque \header, \midi y \layout son ámbitos anidados dentro del ámbito de nivel superior.

Tanto las variables como los ámbitos están implementados en el sistema de módulos de GUILE. A cada ámbito se adjunta un módulo anónimo de Scheme. Una asignación de la forma:

traLaLa = { c'4 d'4 }

se convierte internamente en una definición de Scheme:

(define traLaLa Valor Scheme de `... ')

Esto significa que las variables de LilyPond y las variables de Scheme se pueden mezclar con libertad. En el ejemplo siguiente, se almacena un fragmento de música en la variable traLaLa, y se duplica usando Scheme. El resultado se importa dentro de un bloque \score por medio de una segunda variable twice:

traLaLa = { c'4 d'4 }

#(define newLa (map ly:music-deep-copy
  (list traLaLa traLaLa)))
#(define twice
  (make-sequential-music newLa))

{ \twice }

[image of music]

En realidad, éste es un ejemplo bastante interesante. La asignación solo tiene lugar después de que el analizador sintáctico se ha asegurado de que no sigue nada parecido a \addlyrics, de manera que necesita comprobar lo que viene a continuación. Lee el símbolo # y la expresión de Scheme siguiente sin evaluarla, de forma que puede proceder a la asignación, y posteriormente ejecutar el código de Scheme sin problema.

El ejemplo anterior muestra cómo ‘exportar’ expresiones musicales desde la entrada al intérprete de Scheme. Lo contrario también es posible. Colocándolo después de $, un valor de Scheme se interpreta como si hubiera sido introducido en la sintaxis de LilyPond. En lugar de definir \twice, el ejemplo anterior podría también haberse escrito como

...
{ $(make-sequential-music (list newLa)) }

Podemos utilizar $ con una expresión de Scheme en cualquier lugar en el que usaríamos \nombre después de haber asignado la expresión de Scheme a una variable nombre. Esta sustitución se produce dentro del ‘analizador léxico’, de manera que LilyPond no llega a darse cuenta de la diferencia.

Sin embargo, existe un inconveniente, el de la medida del tiempo. Si hubiésemos estado usando $ en vez de # para definir newLa en el ejemplo anterior, la siguiente definición de Scheme habría fracasado porque traLaLa no habría sido definida aún. Para ver una explicación de este problema de momento temporal, véase Sintaxis del Scheme de LilyPond.

En cualquier caso, la evaluación del código de Scheme se produce dentro del analizador sintáctico como muy tarde. Si necesitamos que se ejecute en un punto temporal más tardío, usaríamos Funciones de Scheme vacías, o lo almacenaríamos en un macro:

#(define (nopc)
  (ly:set-option 'point-and-click #f))

...
#(nopc)
{ c'4 }

Advertencias y problemas conocidos

No es posible mezclar variables de Scheme y de LilyPond con la opción ‘--safe’.


Otros idiomas: English, deutsch, français.
About automatic language selection.

LilyPond — Extender