Was ist der Unterschied zwischen Push und Add-to-List?

26

Ich habe festgestellt, dass verschiedene Pakete in ihren Installationsanweisungen entweder push oder add-to-list verwenden (z. B. ein Verzeichnis zum Ladepfad hinzufügen), und ich habe mich gefragt, was der Unterschied ist und was der Anwendungsfall für jedes ist.

Schattendieb
quelle
1
Ich hatte Mühe, Code mit add-to-listin Code mit umzuwandeln cl-pushnew, und fand diesen Blog-Beitrag ziemlich aufschlussreich: yoo2080.wordpress.com/2013/09/11/…
dangom

Antworten:

21

Was #zck erwähnt, ist ein Unterschied. Aber wenn das der einzige Unterschied wäre, könnte man nach cl-pushnewund fragen add-to-list.

Ein weiterer wichtiger Unterschied: add-to-listist eine Funktion, dh sie wertet alle Argumente aus, insbesondere das erste. pushist ein Makro (wie es ist cl-pushnew) - es wertet sein zweites Argument nicht aus; Stattdessen wird es als verallgemeinerter Ort interpretiert.

Wenn das zweite Argument beispielsweise ein Symbol ist, wird es als Variable betrachtet, und der Wert des ersten Arguments wird auf den Wert dieses Symbols als Variable angewendet, und die Variable wird auf diese neuen Nachteile gesetzt.

Wie die Doc-Zeichenfolge von add-to-listsagt:

This is handy to add some elements to configuration variables,
but please do not abuse it in Elisp code, where you are usually
better off using `push' or `cl-pushnew'.
Drew
quelle
6
Auch nach Angaben des Byte-Compilers:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba
(push (5 6) my-list)gibt mir trotzdem einen fehler - 5ist keine funktion. Wie ist das anders als add-to-listdas Verhalten von?
markasoftware
@markasoftware: Was versuchst du zu tun? Wenn Sie die Liste (5 6)an die Stelle (Wert der Variablen) verschieben möchten, müssen Sie die Liste my-listerstellen (5 6). Eine Möglichkeit, dies zu tun, ist die Verwendung von '(5 6); eine andere ist zu benutzen (list 5 6). pushwertet das Argument aus.
Drew
@Drew Sie sagen jetzt, dass es das Argument bewertet, aber Ihre Antwort sagt wörtlich "es bewertet nicht sein erstes Argument", was die Quelle meiner Verwirrung ist.
markasoftware
@markasoftware: Es tut mir leid; Ich hatte einen Tippfehler - ich schrieb "erstes Argument", wo ich "zweites Argument" hätte schreiben sollen. Jetzt korrigiert - danke. Das zweite Argument pushist ein Ort, z. B. eine Variable. Das erste Argument wird ausgewertet, auf den Wert dieser Variablen bezogen, und die Variable wird auf diese neuen Nachteile gesetzt. add-to-listwertet sein erstes Argument aus, um die Variable zu erzeugen, deren Wert aktualisiert wird. pushwertet das zweite Argument nicht aus, bei dem es sich um die zu aktualisierende Variable handelt. Die Arg-Reihenfolge ist zwischen den beiden umgekehrt.
Drew
15

Noch ein Unterschied:

pushFügt ein Element am Anfang der Liste hinzu .

add-to-listErmöglicht das Hinzufügen eines Elements am Anfang oder Ende der Liste .

(setq testasdf nil)

(push 'a testasdf)

testasdf
(a)

(add-to-list 'testasdf 'b)

testasdf
(b a)

;; add element to the end
(add-to-list 'testasdf "hello" t)

testasdf
(b a "hello")
undostres
quelle
14

Aus der Emacs-Dokumentation oder C-h f push:

Makro: Name der Push-Elementliste

Dieser Makro erstellt eine neue Liste, deren Auto Element ist und deren CDR die durch Listenname angegebene Liste ist, und speichert diese Liste in Listenname.

Von derselben Seite oder C-h f add-to-list:

Funktion: Add-to-List-Symbolelement & optionaler Anhang compare-fn

Diese Funktion setzt das Variablensymbol, indem das Element auf den alten Wert gesetzt wird, falls das Element noch kein Mitglied dieses Werts ist.

Drückt also add-to-listnur, wenn das Element noch nicht da ist.

zck
quelle
cl-pushnewbenimmt sich wie add-to-list.
Sam Boosalis