¿Es posible edebug una lambda devuelta por una función?

7

Por ejemplo,

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

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

(square-two)
Russ Kiselev
fuente

Respuestas:

6

Edebug no admite código de instrumentación construido en tiempo de ejecución. Si intenta instrumentar create-function, el paso se producirá cuando evalúe (create-function 2), no cuando ejecute square-two.

Sin lambdaembargo, Edebug admite formas de instrumentación , por lo que puede reescribir su ejemplo utilizando el enlace léxico:

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

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

Luego, si instrumenta get-lexical-function antes de evaluar el defaliasformulario, puede recorrerlo lambdacuando evalúe square-two.

npostavs
fuente
2

Si.

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)

Use dpara recorrer la función. Use cpara saltear un paso (salte los subpasos). Y, como siempre, C-h mle brinda más información sobre el depurador, incluidas otras claves.

Dibujó
fuente
2
El título de la pregunta mencionada edebug, no debug.
npostavs
@npostavs: Esperemos que alguien publique una respuesta específica para edebug. No uso edebug, así que no puedo evitarlo. Si edebug no se puede usar para tal caso de uso (lo intenté brevemente, pero no encontré una solución útil), una alternativa es usar el estándar debug. Pero me imagino que edebug también se puede usar para esto.
Dibujó el
Sí, me interesan principalmente edebug. He intentado usar edebug-on-entrycon poco éxito.
Russ Kiselev
1

Por cierto, aunque la solución de npostavs es la mejor opción para su ejemplo, en aquellos casos en los que realmente necesita construir el código manualmente con comillas inversas (por ejemplo, dentro defmacro), puede intentar:

(defun create-function (number)
  (edebug-\` (lambda () (* ,number ,number))))
Stefan
fuente
Hmm, es interesante, pero no puedo hacer que funcione. Consigo (invalid-function square-two). El cambio a (defmacro create-function (number) (edebug-` (* ,number ,number)))produce código de trabajo, pero aún no puedo lograr pasarlo.
npostavs
Hmm ... supongo que está roto de alguna manera, entonces. Sé que lo he visto funcionar (cuando me topé con él hace algunos años mientras intentaba arreglar algo en Edebug), pero nunca lo he usado realmente.
Stefan