Ist es möglich, ein von einer Funktion zurückgegebenes Lambda zu beheben?

7

Zum Beispiel,

(defun create-function (number)
  `(lambda () (* ,number ,number)))

(defalias 'square-two (create-function 2) "adds two")

(square-two)
Russ Kiselev
quelle

Antworten:

6

Edebug unterstützt keinen zur Laufzeit erstellten Instrumentierungscode. Wenn Sie versuchen zu instrumentieren create-function, tritt das Stepping bei der Auswertung auf (create-function 2), nicht bei der Ausführung square-two.

Edebug unterstützt jedoch Instrumentierungsformulare lambda, sodass Sie Ihr Beispiel mithilfe der lexikalischen Bindung neu schreiben können:

;;; -*- lexical-binding: t -*-
(defun get-lexical-function (number)
  (lambda () (* number number)))

(defalias 'square-two (get-lexical-function 2) "adds two")

Wenn Sie dann get-lexical-function vor der Auswertung des defaliasFormulars instrumentieren , können Sie bei der Auswertung die Schritte schrittweise lambdaausführen square-two.

npostavs
quelle
2

Ja.

M-x debug-on-entry RET square-two RET

M-: (square-two) RET

Debugger entered--entering a function:
* square-two()
  eval((square-two) nil)
  eval-expression((square-two) nil nil 127)
  funcall-interactively(eval-expression (square-two) nil nil 127)
  call-interactively(eval-expression nil nil)
  command-execute(eval-expression)

Verwenden Sie ddiese Option, um die Funktion zu durchlaufen. Verwenden Sie cdiese Option, um einen Schritt zu überspringen (Unterschritte überspringen). Und wie immer C-h merfahren Sie mehr über den Debugger, einschließlich anderer Schlüssel.

Drew
quelle
2
Der erwähnte edebugFragentitel nicht debug.
Npostavs
@npostavs: Hoffentlich wird jemand eine Antwort speziell für edebug posten. Ich benutze keinen Edebug, also kann ich dort nicht helfen. Wenn edebug für einen solchen Anwendungsfall nicht verwendet werden kann (ich habe es kurz versucht, aber keine nützliche Lösung gefunden), besteht eine Alternative darin, den Standard zu verwenden debug. Aber ich stelle mir vor, dass edebug auch dafür verwendet werden kann.
Drew
Ja, ich interessiere mich hauptsächlich für edebug. Ich habe versucht, edebug-on-entryzu wenig Erfolg zu haben.
Russ Kiselev
1

Übrigens, während die Lösung von npostavs die bessere Option für Ihr Beispiel ist, können Sie in den Fällen, in denen Sie den Code wirklich manuell mit Backquotes (z. B. im Inneren defmacro) erstellen müssen, Folgendes versuchen:

(defun create-function (number)
  (edebug-\` (lambda () (* ,number ,number))))
Stefan
quelle
Hmm, es ist interessant, aber ich kann es nicht ganz zum Laufen bringen. Ich verstehe (invalid-function square-two). Das Ändern auf (defmacro create-function (number) (edebug-` (* ,number ,number)))erzeugt Arbeitscode, aber ich kann es immer noch nicht schaffen, ihn durchzugehen.
Npostavs
Hmm ... dann ist es wohl irgendwie kaputt. Ich weiß, dass ich gesehen habe, wie es funktioniert (damals, als ich vor einigen Jahren darauf gestoßen bin, als ich versucht habe, etwas in Edebug zu reparieren), aber ich habe es nie wirklich genutzt.
Stefan