cl-destructuring-bind auf partieller plist?


9

Dies verursacht einen Fehler

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

weil der :cSchlüssel / Wert in der Musterübereinstimmung nicht behandelt wird.

Oft möchte ich eine Teilmenge von Schlüsseln / Werten aus einer Liste extrahieren, bin aber cl-destructuring-bindaufgrund dieser Einschränkung nicht geeignet.

Gibt es eine Möglichkeit, nicht cl-destructuring-bindübereinstimmende Schlüssel im EXPR einfach zu ignorieren? Ich bin mir nicht sicher, wie das offizielle allgemeine Lisp-Verhalten hier aussehen soll. Ist der Fehler in der Spezifikation?

Beachten Sie, dass die Dash-Bibliothek eine ähnliche Destrukturierung unterstützt, für die jedoch ein -letBoilerplate erforderlich ist, um jedem Schlüssel ein Symbol zuzuweisen. Ein Fix wurde vorgeschlagen

Unter Berücksichtigung der Antwort von Stefan funktioniert dies gut:

(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)

Antworten:


10

Da cl-destructuring-binddie Arglist-Konvention von CommonLisp verwendet wird, sollten Sie in der Lage sein:

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

1
Nicht nur "sollte in der Lage sein". Es funktioniert tatsächlich.
— Harald Hanche-Olsen

Ich schrieb einen Makro, um es einfacher zu bedienen
— fommil

Ich habe einige seltsame, nicht reproduzierbare Fehler mit diesem Makro erhalten. Ist cl-destructuring-bindbekannt, dass es Probleme gibt? github.com/ensime/ensime-emacs/issues/458
— fommil

Ich glaube nicht, dass es bekannte Probleme gibt cl-destructuring-bind(nun, es gibt einige kleinere Probleme, aber keine, die zu falschem Verhalten führen sollten, AFAIK). OTOH Ich bin mir nicht sicher, wie stark es getestet wurde.
— Stefan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.