Format es una función en Common Lisp que puede producir texto formateado usando una cadena de formato similar a la cadena de formato printf . Proporciona más funcionalidad que printf
, permitiendo al usuario generar números en inglés, aplicar ciertos especificadores de formato solo bajo ciertas condiciones, iterar sobre estructuras de datos y generar en un formato tabular. Esto se origina funcionalmente en Lisp Machine Lisp del MIT , donde se basó en Multics ioa_
[ cita requerida ] .
Especificación
La format
función está especificada por la sintaxis [1]
formato de destino controlString & rest formatArguments
Las directivas de la cadena de control se interpolan utilizando los argumentos de formato y la secuencia de caracteres así construida se escribe en el destino.
Destino
El destino puede ser un flujo, una cadena dinámica T
o la NIL
constante; el último de los cuales presenta un caso especial en el sentido de que crea, formatea y devuelve un nuevo objeto de cadena, mientras que se T
refiere a la salida estándar, que generalmente es equivalente a la consola. Los flujos en Common Lisp comprenden, entre otros, la salida de cadenas y los flujos de archivos; por lo tanto, al ser capaz de escribir en una variedad de destinos, esta función unifica capacidades distribuidas entre distintos comandos en algunos otros lenguajes de programación, como C printf
para salida de consola, sprintf
para formateo de cadenas y fprintf
para escritura de archivos.
La multitud de tipos de destinos se ejemplifica a continuación:
;; Imprime "1 + 2 = 3" en la salida estándar y devuelve "NIL". ( formato T "1 + 2 = ~ d" 3 );; Crea y devuelve una nueva cadena que contiene "1 + 2 = 3". ( formato NIL "1 + 2 = ~ d" 3 );; Crea y devuelve una nueva cadena que contiene "1 + 2 = 3". ( con-salida-a-cadena ( salida ) ( formato de salida "1 + 2 = ~ d" 3 ));; Escribe en el archivo "outputFile.txt" la cadena "1 + 2 = 3". ( con-archivo-abierto ( salida "outputFile.txt" : dirección : salida : si-no-no-existe : crear : si-existe : agregar ) ( formatear la salida "1 + 2 = ~ d" 3 ));; Añade a la cadena dinámica la cadena "1 + 2 = 3". ( let (( output-string ( make-array 0 : element-type 'character : ajustable T : fill-pointer 0 ))) ( declare ( type string output-string )) ( format output-string "1 + 2 = ~ d " 3 ) ( la cadena de salida ))
Controlar la cadena y los argumentos de formato
La cadena de control puede contener caracteres literales, así como el meta carácter ~
(tilde), que demarca las directivas de formato . Mientras que los literales en la entrada se repiten textualmente, las directivas producen una salida especial, a menudo consumiendo uno o más argumentos de formato.
Directivas
Una directiva de formato, introducida por a ~
, va seguida de cero o más parámetros de prefijo, cero o más modificadores y el tipo de directiva. Una definición de directiva, por lo tanto, debe ajustarse al patrón
~ [ prefixParameters ] [ modificadores ] directiveType
El tipo de directiva siempre se especifica mediante un solo carácter, que no distingue entre mayúsculas y minúsculas en el caso de las letras. Los datos que se procesarán mediante una directiva de formato, si es necesario, se denominan argumento de formato y pueden ser cero o más objetos de cualquier tipo compatibles. La aceptación de dichos datos y la cantidad de estos datos depende de la directiva y de los posibles modificadores que se les apliquen. El tipo de directiva ~%
, por ejemplo, se abstiene del consumo de cualquier argumento de formato, mientras que ~d
espera que se imprima exactamente un número entero y ~@{
, una directiva influenciada por el modificador at-sign, procesa todos los argumentos restantes.
La siguiente directiva, ~b
espera un objeto numérico de los argumentos de formato y escribe su binario (base 2) equivalente a la salida estándar.
( formato T "~ b" 5 )
Cuando las configuraciones son permisivas, se pueden especificar parámetros de prefijo.
Parámetros de prefijo
Los parámetros de prefijo permiten una inyección de información adicional en una directiva sobre la que operar, similar a la operación de parámetros cuando se proporciona a una función. Los parámetros de prefijo son siempre opcionales y, si se proporcionan, deben ubicarse entre el tipo de introducción ~
y los modificadores o, si no hay ninguno presente, el tipo de directiva. Los valores están separados por comas, pero no toleran espacios en blanco en ninguno de los lados. El número y tipo de estos parámetros depende de la directiva y de la influencia de los modificadores potenciales.
Se pueden utilizar dos caracteres particulares como valores de parámetro de prefijo con interpretación distintiva: v
o V
actúa como un marcador de posición para un número entero o carácter de los argumentos de formato que se consume y se coloca en su lugar. El segundo carácter especial,, #
se sustituye por el recuento de argumentos de formato que respetan su consumo. Ambos v
y #
habilitan el comportamiento definido por el contenido dinámico inyectado en la lista de parámetros de prefijo.
El v
valor del parámetro introduce una funcionalidad equivalente a una variable en el contexto de la programación general. Dado este escenario simple, para rellenar a la izquierda una representación binaria del número entero 5
a al menos ocho dígitos con ceros, la solución literal es la siguiente:
( formato T "~ 8'0b" 5 )
Sin embargo, el primer parámetro de prefijo que controla el ancho de salida puede definirse en términos del v
carácter, delegando la especificación del valor del parámetro al siguiente argumento de formato, en nuestro caso 8
.
( formato T "~ v, '0b" 8 5 )
Las soluciones de este tipo son particularmente beneficiosas si partes de la lista de parámetros de prefijo se describirán mediante variables o argumentos de función en lugar de literales, como es el caso del siguiente fragmento de código:
( deje (( número-de-dígitos 8 )) ( declare ( escriba ( entero 0 * ) número-de-dígitos )) ( formato T "~ v, '0b" número-de-dígitos 5 ))
Aún más apropiado en aquellas situaciones que involucran entrada externa, un argumento de función se puede pasar a la directiva de formato:
( defun print-as-hexadecimal ( number-to-format number-of-digits ) "Imprime el NUMBER-TO-FORMAT en el sistema hexadecimal (base 16), relleno a la izquierda con ceros hasta al menos NUMBER-OF-DIGITS. " ( declare ( escriba número número a formato )) ( declare ( escriba ( entero 0 * ) número de dígitos )) ( formato T " ~ v, '0x " número de dígitos número a formato ) )( imprimir como hexadecimal 12 2 )
#
como parámetro de prefijo, registra los argumentos de formato que aún no han sido procesados por las directivas precedentes, sin consumir nada de esta lista. La utilidad de tal valor insertado dinámicamente está preponderantemente restringida a los casos de uso que pertenecen al procesamiento condicional. Como el número de argumento solo puede ser un número entero mayor o igual a cero, su significado coincide con el de un índice en las cláusulas de una ~[
directiva condicional .
La interacción del #
valor del parámetro de prefijo especial con la directiva de selección condicional ~[
se ilustra en el siguiente ejemplo. La condición establece cuatro cláusulas, accesibles a través de los índices 0, 1, 2 y 3 respectivamente. El número de argumentos de formato se emplea como medio para la recuperación del índice de la cláusula; para hacerlo, insertamos #
en la directiva condicional que permite que el índice sea un parámetro de prefijo. #
calcula el recuento de argumentos de formato y sugiere este número como índice de selección. Los argumentos, no consumidos por este acto, están disponibles y procesados por las directivas de la cláusula seleccionada.
;; Imprime "ninguno seleccionado". ( formato T "~ # [ninguno seleccionado ~; uno seleccionado: ~ a ~; dos seleccionados: ~ a y ~ a ~:; más seleccionados: ~ @ {~ a ~ ^, ~} ~]" );; Imprime "uno seleccionado: CONEJITO". ( formato T "~ # [ninguno seleccionado ~; uno seleccionado: ~ a ~; dos seleccionados: ~ ay ~ a ~:; más seleccionados: ~ @ {~ a ~ ^, ~} ~]" 'conejito );; Imprime "dos seleccionados: CONEJITO y PALOMA". ( formato T "~ # [ninguno seleccionado ~; uno seleccionado: ~ a ~; dos seleccionados: ~ ay ~ a ~:; más seleccionados: ~ @ {~ a ~ ^, ~} ~]" 'paloma ' conejito );; Imprime "más seleccionados: CONEJITO, PALOMA, RATÓN". ( formato T "~ # [ninguno seleccionado ~; uno seleccionado: ~ a ~; dos seleccionados: ~ ay ~ a ~:; más seleccionados: ~ @ {~ a ~ ^, ~} ~]" 'conejito ' paloma ' ratón )
Modificadores
Los modificadores actúan en la capacidad de banderas con la intención de influir en el comportamiento de una directiva. La admisión, la magnitud de la modificación del comportamiento y el efecto, al igual que con los parámetros de prefijo, depende de la directiva. En algunos casos graves, la sintaxis de una directiva puede variar hasta el punto de invalidar ciertos parámetros de prefijo; este poder distingue especialmente a los modificadores de la mayoría de los parámetros. Los dos caracteres modificadores válidos son @
(signo arroba) y :
(dos puntos), posiblemente en combinación como :@
o @:
.
El siguiente ejemplo ilustra un caso bastante leve de influencia ejercida sobre una directiva por el @
modificador: simplemente asegura que la representación binaria de un número formateado siempre esté precedida por el signo del número:
( formato T "~ @ b" 5 )
Directivas de formato
A continuación se presenta una enumeración de las directivas de formato, incluida su sintaxis completa y sus efectos modificadores. [2]
Personaje Descripción ~ Imprime el literal ~ personaje. Forma completa: .
~repetitions~
Sin modificador: imprime el
repetitions
tiempo del~
personaje.:
modificador: no válido.@
modificador: no válido.:@
modificador: no válido.c , C Imprime un solo carácter. Forma completa: .
~c
Sin modificador: imprime el carácter de argumento de formato sin prefijo.
:
modificador: Deletrea los caracteres que no se imprimen.@
modificador: antepone el#\
prefijo legible .:@
modificador: Deletrea los caracteres que no se imprimen y menciona las teclas de mayúsculas.% Imprime una nueva línea incondicional. Forma completa: .
~repetitions%
Sin modificador: imprime
repetitions
saltos de línea.:
modificador: no válido.@
modificador: no válido.:@
modificador: no válido.Y Imprime una nueva línea condicional o una nueva línea. Forma completa: .
~repetitions&
Sin modificador: si el destino no está al comienzo de una línea nueva, imprime
repetitions
saltos de línea; de lo contrario, imprimerepetitions
: saltos de 1 línea.:
modificador: no válido.@
modificador: no válido.:@
modificador: no válido.| Imprime un separador de páginas. Forma completa: .
~repetitions|
Sin modificador: imprime el
repetitions
tiempo de un separador de página.:
modificador: no válido.@
modificador: no válido.:@
modificador: no válido.r , R Imprime el número en la base especificada (raíz) o lo deletrea. Forma completa: .
~radix,minColumns,padChar,commaChar,commaIntervalR
Con parámetros de prefijo, imprime el argumento en la raíz (base).
Sin parámetros de prefijo, el argumento de formato está escrito, ya sea en letras inglesas o en números romanos.
Sin modificador: imprime el argumento como un número en inglés.
:
modificador: escribe el argumento en números ordinales en inglés.@
modificador: imprime el argumento en números romanos utilizando el formato romano habitual (por ejemplo, 4 = IV).:@
modificador: imprime el argumento en números romanos utilizando el antiguo formato romano (por ejemplo, 4 = IIII).d , D Imprime el argumento en base decimal (base = 10). Forma completa: .
~radix,minColumns,padChar,commaChar,commaIntervald
Sin modificador: se imprime como un número decimal sin el
+
signo (más) ni el separador de grupo.:
modificador: utiliza comas como separador de grupos.@
modificador: antepone el signo.:@
modificador: antepone el signo y utiliza comas como separador de grupo.b , B Imprime el argumento en base binaria (base = 2). Forma completa: .
~radix,minColumns,padChar,commaChar,commaIntervalb
Sin modificador: se imprime como un número binario sin el
+
signo (más) ni el separador de grupo.:
modificador: utiliza comas como separador de grupos.@
modificador: antepone el signo.:@
modificador: antepone el signo y utiliza comas como separador de grupo.o , O Imprime el argumento en base octal (base = 8). Forma completa: .
~radix,minColumns,padChar,commaChar,commaIntervalo
Sin modificador: se imprime como un número octal sin el
+
signo (más) ni el separador de grupo.:
modificador: utiliza comas como separador de grupos.@
modificador: antepone el signo.:@
modificador: antepone el signo y utiliza comas como separador de grupo.x , X Imprime el argumento en base hexadecimal (base = 16). Forma completa: .
~radix,minColumns,padChar,commaChar,commaIntervalx
Sin modificador: se imprime como un número hexadecimal sin el
+
signo (más) ni el separador de grupo.:
modificador: utiliza comas como separador de grupos.@
modificador: antepone el signo.:@
modificador: antepone el signo y utiliza comas como separador de grupo.f , F Imprime el argumento como flotante en notación de punto fijo. Forma completa: .
~width,numDecimalPlaces,scaleFactor,overflowChar,padCharf
Sin modificador: se imprime como punto fijo sin el
+
signo (más).:
modificador: no válido.@
modificador: antepone el signo.:@
modificador: no válido.e , mi Imprime el argumento como flotante en notación exponencial. Forma completa: .
~width,numDecimalPlaces,numDigits,scaleFactor,overflowChar,padChar,exponentChare
Sin modificador: se imprime como exponencial sin el
+
signo (más).:
modificador: no válido.@
modificador: antepone el signo.:@
modificador: no válido.g , GRAMO Imprime el argumento como flotante en notación de punto fijo o exponencial, eligiendo automáticamente. Forma completa: .
~width,numDecimalPlaces,numDigits,scaleFactor,overflowChar,padChar,exponentCharg
Sin modificador: se imprime como punto fijo o exponencial sin el
+
signo (más).:
modificador: no válido.@
modificador: antepone el signo.:@
modificador: no válido.PS Imprime el argumento de acuerdo con las convenciones monetarias. Forma completa: .
~width,numDigits,minWholeDigits,minTotalWidth,padChar$
Sin modificador: imprime en convenciones monetarias sin el
+
signo (más) ni relleno.:
modificador: antepone el signo antes de rellenar caracteres.@
modificador: antepone el signo.:@
modificador: no válido.una , A Imprime el argumento de una manera amigable para los humanos. Forma completa: .
~minColumns,colInc,minPad,padChara
Sin modificador: imprime resultados amigables para los humanos sin justificación.
:
modificador: se imprimeNIL
como una lista vacía en()
lugar deNIL
.@
modificador: almohadillas a la izquierda en lugar de a la derecha.:@
modificador: almohadillas a la izquierda y se imprimeNIL
como()
.s , S Imprime el argumento de una manera compatible con la read
función.Forma completa: .
~minColumns,colInc,minPad,padChars
Sin modificador: Imprime
read
-compatible sin justificación.:
modificador: se imprimeNIL
como una lista vacía en()
lugar deNIL
.@
modificador: almohadillas a la izquierda en lugar de a la derecha.:@
modificador: almohadillas a la izquierda y se imprimeNIL
como()
.w , W Imprime el argumento de acuerdo con las variables de control de la impresora. Forma completa: .
~w
Sin modificador: imprime de acuerdo con las variables de control configuradas actualmente.
:
modificador: permite una impresión bonita.@
modificador: ignora el nivel de impresión y las restricciones de longitud.:@
modificador: ignora el nivel de impresión y las restricciones de longitud y permite una impresión bonita._ Imprime un salto de línea de acuerdo con las bonitas reglas de la impresora. Forma completa: .
~_
Sin modificador: imprime un salto de línea si se excede una sola línea.
:
modificador: imprime un salto de línea si no precede una sola línea.@
modificador: usa un estilo compacto ( avaro ).:@
modificador: siempre inserta un salto de línea.< Justifica la salida. Forma completa: .
~minColumns,colInc,minPad,padChar<expression~>
Sin modificador: justifica a la izquierda la salida.
:
modificador: agrega relleno a la izquierda (= justifica a la derecha).@
modificador: agrega relleno a la derecha (= justifica a la izquierda).:@
modificador: Centra el texto.i , I Sangra un bloque lógico. Forma completa: .
~i
Sin modificador: comienza a sangrar desde el primer carácter.
:
modificador: sangría a partir de la posición de salida actual.@
modificador: no válido.:@
modificador: no válido./ Envía la operación de formateo a una función definida por el usuario. La función debe aceptar al menos cuatro parámetros: (1) La secuencia o cadena ajustable para imprimir, (2) el argumento de formato para procesar, (3) un valor booleano que es T
si:
se proporcionó el modificador, y (4) un valor booleano valor que esT
si@
se proporcionó el modificador. Además, se pueden especificar cero o más argumentos si la función también debe permitir parámetros de prefijo.Forma completa: .
~prefixParams/function/
Sin modificador: Depende de la implementación de la función.
:
modificador: Depende de la implementación de la función.@
modificador: Depende de la implementación de la función.:@
modificador: Depende de la implementación de la función.t , T Mueve el cursor de salida a una columna determinada o una distancia horizontal. Forma completa: .
~columnNumber,columnIncrementt
Sin modificador: va a la columna especificada.
:
modificador: Orienta en la sección.@
modificador: Mueve el cursor en relación con la posición actual.:@
modificador: Orienta con respecto a la sección.* Navega por los argumentos de formato. Forma completa: .
~numberOfArgs*
Sin modificador: omite los
numberOfArgs
argumentos de formato.:
modificador:numberOfArgs
retrocede.@
modificador: se desplaza al argumento en el índicenumberOfArgs
.:@
modificador: no válido.[ Imprime una expresión basada en una condición. Estas expresiones, o cláusulas , están separadas por la ~;
directiva y se puede establecer una cláusula predeterminada utilizando~:;
como separador inicial. El número de cláusulas permitidas depende de la variedad concreta de esta directiva según lo establecido por su modificador o modificadores. Toda la parte condicional debe terminar con a~]
.Forma completa: .
~[clause1~;...~;clauseN~:;defaultClause~]
Existe una forma alternativa, válida solo sin modificadores, que reubica el índice de la cláusula a seleccionar
selectionIndex
, de los argumentos de formato a un parámetro de prefijo:Forma completa: .
~selectionIndex[clause1~;...~;clauseN~:;defaultClause~]
Esta sintaxis se recomienda a sí misma especialmente en conjunto con el carácter de parámetro de prefijo especial
#
que equipara el elemento seleccionado con el número de argumentos de formato que quedan por procesar. Una directiva de este tipo permite un modelado muy conciso de múltiples selecciones.Sin modificador: El argumento de formato debe ser un índice entero de base cero, siendo su valor el de la cláusula para seleccionar e imprimir.
:
modificador: Selecciona la primera cláusula si el argumento de formato esNIL
, de lo contrario, la segunda.@
modificador: solo procesa la cláusula si el argumento de formato esT
; de lo contrario, lo omite.:@
modificador: no válido.{ Repite uno o más argumentos de formato y los imprime. La parte iterativa debe cerrarse con una ~}
directiva. Si la directiva~^
se encuentra dentro de la parte adjunta, cualquier contenido que la siga solo se consume si el elemento actual no es el último en la lista procesada. SinumberOfRepetitions
se especifica el parámetro de prefijo , su valor define el número máximo de elementos a procesar; de lo contrario, todos estos se consumen.Forma completa: .
~numberOfRepetitions{expression~}
Sin modificador: se espera que un argumento de formato único sea una lista, sus elementos se consumen en orden por las directivas adjuntas.
:
modificador: espera que el argumento de formato sea una lista de listas, consumiendo sus sublistas.@
modificador: considera todos los argumentos de formato restantes como una lista y los consume.:@
modificador: considera todos los argumentos de formato restantes como una lista de sublistas, consumiendo estas sublistas.? Sustituye la directiva por el siguiente argumento, que se espera que sea un argumento de formato, utilizando los argumentos de formato subsiguientes en la nueva parte. Forma completa: .
~?
Sin modificador: espera que los argumentos de formato subsiguientes sean una lista cuyos elementos están asociados con la cadena de control insertada.
:
modificador: no válido.@
modificador: espera argumentos de formato separados en lugar de una lista de estos para la parte insertada, como se especificaría de la manera habitual.:@
modificador: no válido.( Modifica el caso de la cadena adjunta. Forma completa: .
~(expression~)
Sin modificador: convierte todos los caracteres a minúsculas.
:
modificador: pone en mayúscula solo la primera palabra, convierte el resto a minúsculas.@
modificador: pone todas las palabras en mayúscula.:@
modificador: convierte todos los caracteres a mayúsculas.p , PAG Imprime un prefijo singular o plural según el argumento de formato numérico. Forma completa: .
~p
Sin modificador: no imprime nada si el argumento es igual a 1; de lo contrario, imprime
s
.:
modificador: Vuelve al último argumento de formato consumido, no imprime nada si era 1, de lo contrario imprimes
.@
modificador: imprime uny
si el argumento es igual a 1, de lo contrario imprimeies
.:@
modificador: Vuelve al último argumento de formato consumido, imprimiendoy
si era 1, en caso contrario imprimiendoies
.^ Se usa en una directiva de iteración para terminar el procesamiento del contenido adjunto si no siguen más argumentos de formato. ~{...~}
Forma completa: .
~p1,p2,p3^
La condición de terminación depende del número de parámetros de prefijo suministrados:
- Si no se especifica ningún parámetro de prefijo, la directiva cesa si quedan cero argumentos para procesar.
- Si
p1
se especifica un parámetro de prefijo , la directiva cesa si sep1
resuelve en cero. - Si se especifican dos parámetros de prefijo
p1
yp2
, la directiva cesa sip1
es igualp2
. - Si se especifican tres parámetros de prefijo
p1
,p2
yp3
, la directiva cesa si se cumple:p1
≤p2
≤p3
.
Sin modificador: funciona como se describe.
:
modificador: no válido.@
modificador: no válido.:@
modificador: no válido.Nueva línea Omite o retiene los saltos de línea y los espacios en blanco adyacentes en una cadena de control de varias líneas. Forma completa: .
~Newline
Sin modificador: omite el salto de línea inmediatamente siguiente y los espacios en blanco adyacentes.
:
modificador: omite el salto de línea inmediatamente siguiente, pero conserva los espacios en blanco adyacentes.@
modificador: retiene el salto de línea inmediatamente siguiente, pero omite los espacios en blanco adyacentes.:@
modificador: no válido.
Ejemplo
Un ejemplo de una printf
llamada C es el siguiente:
printf ( "Color% s, número1% d, número2% 05d, hexadecimal% x, flotante% 5.2f, valor sin signo% u. \ n " , "rojo" , 123456 , 89 , 255 , 3.14 , 250 );
Usando Common Lisp, esto es equivalente a:
( formato t "Color ~ A, número1 ~ D, número2 ~ 5, '0D, hexadecimal ~ X, flotante ~ 5,2F, valor sin signo ~ D. ~%" "rojo" 123456 89 255 3,14 250 ) ;; Impresiones: Color rojo, número1 123456, número2 00089, FF hexadecimal, flotante 3.14, valor sin firmar 250.
Otro ejemplo sería imprimir cada elemento de la lista delimitado con comas, lo que se puede hacer usando la ~ { , ~ ^ y ~ } directivas: [3]
( let (( groceries ' ( huevos pan mantequilla zanahorias ))) ( formato t "~ {~ A ~ ^, ~}. ~%" comestibles ) ; Se imprime en mayúsculas ( formato t "~: (~ {~ A ~ ^ , ~} ~). ~% " comestibles )) ; Capitaliza la producción ;; estampas: HUEVOS, PAN, MANTEQUILLA, ZANAHORIAS. ;; estampados: Huevos, Pan, Mantequilla, Zanahorias.
Tenga en cuenta que no solo se itera la lista de valores directamente por format
, sino que las comas se imprimen correctamente entre los elementos, no después de ellos. Un ejemplo aún más complejo sería imprimir una lista utilizando la redacción habitual en inglés:
( let (( template "Los afortunados ganadores fueron: ~ # [ninguno ~; ~ S ~; ~ S y ~ S ~ ~:; ~ @ {~ # [~; y ~] ~ S ~ ^, ~} ~] . " )) ( formato de plantilla nula ) ;; ⇒" Los afortunados ganadores fueron: ninguno. " ( formato nulo plantilla 'foo ) ;; ⇒" Los afortunados ganadores fueron: FOO. " ( formato nulo plantilla ' foo 'barra ) ; ; ⇒ "Los afortunados ganadores fueron: FOO y BAR." ( Formato nulo plantilla 'foo ' bar 'baz ) ;; ⇒ "Los afortunados ganadores fueron: FOO, BAR y BAZ." ( Formato nulo plantilla ' foo 'bar ' baz 'quux ) ;; ⇒ "Los afortunados ganadores fueron: FOO, BAR, BAZ y QUUX." )
La capacidad de definir una nueva directiva proporciona los medios para la personalización. El siguiente ejemplo implementa una función que imprime una cadena de entrada en minúsculas, mayúsculas o estilo inverso, permitiendo también una configuración del número de repeticiones.~/functionName/
( defun mydirective ( argumento de formato de destino modificador de dos puntos-suministrado-p modificador de signo-at-suministrado-p & opcional ( repeticiones 1 )) "Esta función representa una devolución de llamada adecuada como directiva en una invocación de` `formato '', esperando una cadena como su FORMATO-ARGUMENTO para imprimir REPETICIONES número de veces al DESTINO. --- Las banderas COLON-MODIFIER-SUPPLIED-P y AT-SIGN-MODIFIER-SUPPLIED-P esperan un booleano generalizado cada una, siendo los representantes de la modificadores ``: '' y `` @ '' respectivamente. Su influencia se define de la siguiente manera: - Si no se establece ningún modificador, el FORMAT-ARGUMENT se imprime sin modificaciones adicionales. - Si se establece el modificador de dos puntos, pero no la arroba. -sign modifier, FORMAT-ARGUMENT se convierte en minúsculas antes de imprimir. - Si se establece el modificador at, pero no el modificador de dos puntos, FORMAT-ARGUMENT se convierte en mayúsculas antes de imprimir. - Si ambos modificadores están configurados, el FORMAT-ARGUMENT se invierte antes de imprimir. --- El número de veces que FORMAT-ARGUMENT st el anillo que se imprimirá está determinado por el parámetro de prefijo REPETICIONES, que debe ser un número entero no negativo y el valor predeterminado es uno. " ( declare ( type ( or null ( eql T ) stream string ) destination )) ( declare ( type T) argumento-formato )) ( declare ( tipo T modificador-de-dos puntos-suministrado-p )) ( declare ( tipo T -modificador-signo-at-suministrado-p )) ( declare ( tipo ( entero 0 * ) repeticiones )) ( Dejar que (( string-to-print formato de argumento )) ( declarar ( tipo de cadena de la cadena-to-print )) ;; Ajuste el STRING-TO-PRINT según los modificadores. ( cond (( y el modificador-de-dos puntos-suministrado-p -modificador-de-signo-arroba-suministrado-p ) ( setf cadena-a-imprimir ( cadena- inversa -a-imprimir ))) ( modificador-de-dos puntos-suministrado-p ( setf cadena -to-imprimir ( cadena-abajo-mayúscula- cadena-a-imprimir ))) ( signo-arroba-modificador-suministrado-p ( setf cadena-a-imprimir ( cadena-arriba-mayúscula cadena-a-imprimir ))) ( T NIL )) ( Bucle de repetición repeticiones hacen ( formato de destino "~ una" impresión cadena a ))));; Imprime "Hola" una sola vez. ( formato T "~ / mydirective /" "Hola" );; Imprime "Hola" tres veces. ( formato T "~ 3 / mydirective /" "Hola" );; Imprime un "Hola" en minúscula (= "hola") tres veces. ( formato T "~ 3: / mydirective /" "Hola" );; Escriba un "Hola" (= "HOLA") en mayúsculas tres veces. ( formato T "~ 3 @ / mydirective /" "Hola" );; Imprime un "Hola" (= "olleH") invertido tres veces. ( formato T "~ 3: @ / mydirective /" "Hola" )
Si bien format
es algo infame por su tendencia a volverse opaco y difícil de leer, proporciona una sintaxis notablemente concisa pero poderosa para una necesidad especializada y común. [3]
Está disponible una tabla de resumen de Common Lisp FORMAT. [4]
Referencias
- ^ "CLHS: Función FORMATO" . www.lispworks.com .
- ^ "CLHS: Sección 22.3" . www.lispworks.com .
- ^ a b 18. Algunas recetas de FORMATO de Practical Common Lisp
- ^ Tabla resumen de Common Lisp FORMAT