cl-destructuring-bind sur plist partiel?


9

Cela provoque une erreur

(cl-destructuring-bind 
    (&key a b) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b)) 

car la :cclé / valeur n'est pas gérée dans la correspondance de modèle.

Souvent, je me retrouve à vouloir extraire un sous-ensemble de clés / valeurs d'un plist, mais ce cl-destructuring-bindn'est pas approprié en raison de cette limitation.

Existe-t-il un moyen de cl-destructuring-bindsimplement ignorer les clés sans correspondance dans l'EXPR? Je ne sais pas quel est le comportement officiel de lisp commun censé être ici, est-ce l'erreur dans la spécification?

Notez que la bibliothèque de tirets prend en charge une déstructuration similaire avec -let, mais cela nécessite un passe-partout pour attribuer un symbole à chaque clé. Un correctif a été proposé

Compte tenu de la réponse de Stefan, cela fonctionne bien:

(defmacro plist-bind (args expr &rest body)
  "`destructuring-bind' without the boilerplate for plists."
  `(cl-destructuring-bind
       (&key ,@args &allow-other-keys)
       ,expr
     ,@body))

(plist-bind
  (a b)
 '(:a "foo" :b 13 :c "bar")
 (list a b)) => ("foo" 13)

Réponses:


10

Puisque cl-destructuring-bindutilise la convention d'arglist de CommonLisp, vous devriez pouvoir faire:

(cl-destructuring-bind 
    (&key a b &allow-other-keys) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b))

1
Pas seulement «devrait pouvoir». Cela fonctionne réellement.
Harald Hanche-Olsen

J'ai écrit une macro pour en faciliter l'utilisation
fommil

J'ai eu des erreurs étranges non reproductibles avec cette macro, est cl-destructuring-bindconnu pour avoir des problèmes? github.com/ensime/ensime-emacs/issues/458
fommil

Je ne pense pas qu'il y ait de problèmes connus dans cl-destructuring-bind(enfin, il y a quelques problèmes mineurs mais aucun qui devrait conduire à un comportement incorrect, AFAIK). OTOH Je ne sais pas à quel point il a été testé.
Stefan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.