2015-08-19 11 views
6

ho cercato attraverso la formattazione ricette, e non riesco a trovare quello che sto cercando ...CL Formato ricetta: Trattare con nil come valore

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

Supponiamo che io don 't voglio cambiare gli argomenti nel modulo sopra, solo CONTROL-STRING.

day e num-apples saranno sempre non nulli, ma name potrebbe essere nullo.

Quando name è pari a zero, voglio l'uscita a guardare come

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

ma quando name è definito, voglio farlo sembrare come

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

Quindi la stringa di controllo ha bisogno di guardare name, usarlo nel caso non-zero, non usarlo nel caso nullo, ma consumarlo in entrambi i casi.

Forse può essere ottenuto consumando nil e stampandolo come ""? Se è così, non so come farlo.

+1

Il mio originale search-fu non era abbastanza buono. Penso che questa sia la mia risposta. http://stackoverflow.com/questions/5729032/lisp-format-directive-that-interprets-nil-argument-to-empty-string-instead-of-n?rq=1 –

risposta

9

La domanda a cui è collegato, Lisp format directive that interprets nil argument to empty string instead of "NIL", include una risposta che mostra come è possibile farlo, ma non cita alcuna documentazione. Poiché stai generando testo in inglese, ci sono anche alcune altre opzioni che potresti voler considerare.

In primo luogo, con ~ @ [conseguente ~], è possibile elaborare la conseguente direttiva formato solo nel caso che l'argomento non è pari a zero, e l'argomento per ~ @ [ non è consumata , quindi è ancora disponibile. In generale, 22.3.7.2 Tilde Left-Bracket: Conditional Expression descrive un sacco di opzioni, ma di ~ @ [ si dice:

~ @ [conseguente ~] mette alla prova l'argomento. Se è vero, l'argomento non viene utilizzato dal comando ~ [ma rimane come il successivo da elaborare e viene elaborata la clausola one conseguente. Se l'argomento è false, l'argomento viene utilizzato e la clausola non viene elaborata. Pertanto la clausola normalmente dovrebbe utilizzare esattamente un argomento e potrebbe aspettarsi che non sia nulla.

È possibile utilizzare questo come segue:

(defun test (day name n-apples) 
    (format nil "Today is ~a. [email protected][ ~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." 

Per renderlo ancora più robusto, si dovrebbe considerare l'utilizzo di ~p for pluralization, in modo che si ottiene "1 mela" e " 3 mela s ".

(defun test (day name n-apples) 
    (format nil "Today is ~a. [email protected][ ~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." 

Infine, dal momento che si sta generando il testo, si potrebbe apprezzare alcuni casi la normalizzazione (ad esempio, stampare nomi propri con l'iniziale maiuscola), e scrivere i numeri nel testo:

(defun test (day name n-apples) 
    (format nil "Today is ~:(~a~). [email protected][ ~:(~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.")