format common-lisp

Receta de formato CL: tratar con nil como valor



common-lisp (1)

La pregunta a la que se vinculó, la directiva de formato Lisp que interpreta un argumento nulo en una cadena vacía en lugar de "NIL" , incluye una respuesta que muestra cómo puede hacerlo, pero no cita ninguna de la documentación. Como está generando texto en inglés, también hay algunas otras opciones que también podría considerar.

En primer lugar, con ~ @ [consecuente ~] , puede procesar la directiva de formato consiguiente justo en el caso de que el argumento sea no nulo, y el argumento para ~ @ [ no se consuma, por lo que todavía está disponible. En general, 22.3.7.2 Tilde Left-Bracket: Conditional Expression describe muchas opciones, pero sobre ~ @ [ dice:

~ @ [consecuente ~] prueba el argumento. Si es verdadero, entonces el argumento ~ no se usa para el argumento ~ [pero permanece como el siguiente para ser procesado, y la cláusula consecuente es procesada. Si el arg es falso, entonces el argumento se agota y la cláusula no se procesa. La cláusula, por lo tanto, normalmente debería usar exactamente un argumento, y puede esperar que sea no nulo.

Puedes usar esto de la siguiente manera:

(defun test (day name n-apples) (format nil "Today is ~a. Hello~@[ ~a~], you have ~a apples." day name n-apples))

CL-USER> (test ''monday ''adam 2) "Today is MONDAY. Hello ADAM, you have 2 apples." CL-USER> (test ''tuesday nil 42) "Today is TUESDAY. Hello, you have 42 apples."

Para que esto sea aún más sólido, debería considerar usar ~ p para la pluralización , de modo que obtenga "1 manzana" y "3 manzanas s ".

(defun test (day name n-apples) (format nil "Today is ~a. Hello~@[ ~a~], you have ~a apple~:P." day name n-apples))

CL-USER> (test ''monday ''john 2) "Today is MONDAY. Hello JOHN, you have 2 apples." CL-USER> (test ''tuesday ''john 1) "Today is TUESDAY. Hello JOHN, you have 1 apple." CL-USER> (test ''wednesday nil 0) "Today is WEDNESDAY. Hello, you have 0 apples."

Finalmente, dado que está generando texto, puede apreciar la normalización de algunos casos (p. Ej., Imprimir sustantivos propios con mayúscula inicial) y escribir los números en el texto:

(defun test (day name n-apples) (format nil "Today is ~:(~a~). Hello~@[ ~:(~a~)~], you have ~r apple~:P." day name n-apples))

CL-USER> (list (test ''monday ''adam 4) (test ''tuesday ''john 1) (test ''wednesday ''mary/ sue 42) (test ''thursday ''jim-bob 0)) ("Today is Monday. Hello Adam, you have four apples." "Today is Tuesday. Hello John, you have one apple." "Today is Wednesday. Hello Mary Sue, you have forty-two apples." "Today is Thursday. Hello Jim-Bob, you have zero apples.")

He estado buscando recetas de formato, y no puedo encontrar lo que estoy buscando ...

(format nil CONTROL-STRING day name num-apples)

Supongamos que no quiero cambiar los argumentos en el formulario anterior, simplemente CONTROL-STRING .

day y num-apples siempre serán no-nil, pero el name podría ser nulo.

Cuando name es nil, quiero que la salida se vea como

"Today is Monday. Hello, you have 3 apples."

pero cuando se define el name , quiero que se vea como

"Today is Monday. Hello Adam, you have 3 apples."

Por lo tanto, la cadena de control debe buscar el name , usarlo en el caso no nulo, no usarlo en el caso nulo, pero consumirlo en ambos casos.

¿Tal vez se puede lograr consumiendo cero e imprimiéndolo como "" ? Si es así, no sé cómo hacer eso.