/ / Wie man Primitive in Emacs berät - Emacs, Elisp, Beratungsfunktionen, Defadvice

Wie kann man Primitive in Emacs beraten?

Ich habe versucht zu antworten eine weitere SO Frage wenn ich auf ein sehr merkwürdiges Verhalten stoße. Hier ist mein kleiner Testfall:

(make-variable-buffer-local
(defvar my-override-mode-on-save nil
"Can be set to automatically ignore read-only mode of a file when saving."))

(defadvice file-writable-p (around my-overide-file-writeable-p act)
"override file-writable-p if `my-override-mode-on-save" is set."
(or
my-override-mode-on-save
ad-do-it))

(defun my-override-toggle-read-only ()
"Toggle buffer"s read-only status, keeping `my-override-mode-on-save" in sync."
(interactive)
(setq my-override-mode-on-save (not my-override-mode-on-save))
(toggle-read-only))

(defun tester-fn ()
(interactive)
(let ((xxx (file-writable-p "/tmp/foofoo"))
(yyy (file-writable-p "/tmp/fooxxfoo")))
(message (concat "XXX: " (if xxx "yes" "no") "   -   YYY: " (if yyy "yes" "no")))))

woher:

  • /tmp/foofoo ist eine schreibgeschützte Datei, die ich besucht und ausgeführt habe my-override-toggle-read-only im.
  • /tmp/fooxxfoo ist nicht vorhanden.
  • /tmp ist schreibbar für den Benutzer, als den ich angemeldet bin.

Wenn ich renne tester-fn in einem Puffer wo my-override-mode-on-save ist eingestellt auf t dann bekomme ich ein unerwartetes Ergebnis: XXX: no - YYY: no. Wenn ich renne tester-fn während in einem anderen Puffer (z.B. kratzen) Ich erhalte die erwartete Antwort im Minipuffer: XXX: no - YYY: yes. Verfolgung des Hinweises durch den Debugger zeigtEs ist genau das zu tun, was ich denke, dass es tun sollte, die Teile auszuführen, die ich erwarte, die Teile zu überspringen, die ich erwarte, und den Wert zurückzugeben, den ich erwarte. Verfolgung jedoch tester-fn durch den Debugger zeigt sehr unterschiedliche Werte zurückgegeben (nil & t Wenn die Variable als null ausgewertet wird, nil & nil wenn die Variable als nicht null ausgewertet wird). Das nil & nil Rückkehr ist wirklich das, was ich bizarr finde.

Ich habe keine Ahnung, was hier passiert. Weiß jemand, warum ich nicht die erwarteten Ergebnisse erhalte?

Antworten:

4 für die Antwort № 1

Ihr Code sieht gut aus, mit Ausnahme des einzigen fehlenden Schlüssels. Sie müssen den Rückgabewert entsprechend einstellen:

(defadvice file-writable-p (around my-overide-file-writeable-p act)
"override file-writable-p if `my-override-mode-on-save" is set."
(setq ad-return-value
(or
my-override-mode-on-save
ad-do-it)))

Dies ist in der dokumentiert Ratgeber.