3 votes

Comment exiger des arguments de mots-clés en Common Lisp ?

Étant donné que

(defun show-arg (a)
  (format t "a is ~a~%" a))

(defun show-key (&key a)
  (format t "a is ~a~%" a))

évaluation de

(show-arg)

conduira à une erreur disant "nombre d'arguments invalide : 0", où

(show-key)

affichera a is NIL

Comment puis-je obtenir SHOW-KEY pour signaler une erreur comme SHOW-ARG fait ? Existe-t-il un autre moyen que d'utiliser (unless a (error "a is required")) dans le corps de fonction ? J'aime beaucoup les arguments de type mot-clé, je les utilise constamment et je souhaite presque toujours qu'ils soient obligatoires.

10voto

jkiiski Points 6521

Les arguments des mots-clés sont toujours facultatifs, vous devez donc vérifier manuellement s'ils sont fournis et signaler une erreur si nécessaire. Il serait cependant préférable de ne pas exiger les arguments mots-clés. Le compilateur ne les reconnaîtra pas comme requis et ne vous donnera donc pas de message d'erreur pour les arguments manquants au moment de la compilation.

Si vous voulez les exiger, vous pouvez spécifier les arguments avec une liste de trois éléments ; le premier élément étant l'argument, le deuxième est la valeur par défaut et le troisième est une variable qui sera vraie si l'argument a été donné. Il est préférable de vérifier le troisième élément plutôt que le mot-clé lui-même, car vous pouvez alors faire la différence entre un mot-clé NIL qui était la valeur par défaut, et un NIL que l'utilisateur a donné comme argument.

(defun foo (&key (keyarg nil keyargp))
  (unless keyargp (error "KEYARG is required."))
  (* keyarg 2))

Modifier

Maintenant que j'y pense un peu plus, il existe en fait un moyen d'obtenir des erreurs de compilation pour les arguments de mots-clés manquants. Définissez une macro de compilation pour la fonction :

(defun foo (&key a b c d)
  (* a b c d))

(define-compiler-macro foo (&whole whole &key (a nil ap) (b nil bp)
                                   (c nil cp) (d nil dp))
  (declare (ignore a b c d))
  (unless (and ap bp cp dp)
    (error "Missing arguments..."))
  whole)

7voto

Rainer Joswig Points 62532

Une possibilité serait :

(defun foo (&key (arg1 (error "missing arg1 in call to function foo")))
   arg1)

L'utiliser :

CL-USER 80 > (foo)

Error: missing arg1 in call to function foo
  1 (abort) Return to level 0.
  2 Return to top loop level 0.

Cela donnera une erreur au moment de l'exécution, mais malheureusement pas au moment de la compilation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X