在 Emacs 和 SLIME 中调试 Common Lisp 的有效方法是什么?
What are efficient ways to debug Common Lisp in Emacs and SLIME?
我想知道使用 Emacs 和 SLIME 以交互方式调试 Common Lisp 的一些有效方法。
我之前的做法:作为学过C的人,Python使用IDE(VS和PyCharm),我习惯设置断点,添加手表,并进行踩踏。但是当我开始使用 CL 时,我发现调试工作流程根本不同。我没有找到设置断点、单步执行和查看变量如何变化的好方法。
我用的笨办法就是在代码里加"print",一遍又一遍的加运行,效率很低。我知道我们可以在 SLIME 中 "inspect" 变量,但不确定如何以交互方式进行。
我发现了什么: 我最近在 development of a Morse code translator 上看到了这个视频,它展示了如何在 SLIME 中进行交互式调试的完整过程,这已经被非常翔实和有启发性。就好像我们可以 "talk" 给编译器。
我想要的: 我在网上搜索但发现很少有教程演示经验丰富的 Lisper 实际上 开发和调试他们的程序。我渴望学习这样的经验。
- 如何交互调试?
- 有哪些好的做法和技巧?如何添加断点和步骤?
- 调试时您最常使用/发现最有用的快捷方式/工具/工作流程是什么?
您可以做很多事情:
- 您可以跟踪函数调用(请参阅 Common Lisp 中的
TRACE
和 UNTRACE
或 slime-toggle-trace-fdefinition*
)。这有助于递归调用:您可以在每个级别看到您传递的内容以及它们 return。
- 标准的东西:在地方添加
(format t ...)
。我想,不用评论了。
- 如果代码中断,您将进入调试器。从那里您可以检查堆栈,查看调用了什么以及传递了哪些参数。请参阅@jkiiski link:它有关于它的非常好的信息,包括
(break)
表单,它将充当断点并让您进入调试器。 剧透警报:您可以更改检查器中的值,您可以更改并重新编译您的代码并从(几乎)堆栈中的任何位置重新启动。
- 最后但同样重要的是:要调试宏,您将需要
slime-macroexpand-1
(MACROEXPAND-1
的包装器),甚至更好的 C-c M-e
用于宏步进器。
最后一个建议:如果您要进行认真的调试,请在您的文件中包含 (declaim (optimize (debug 3)))
,否则某些 CL 实现倾向于优化堆栈上的调用或使参数不可访问。
使用 Common Lisp 和 Slime,您可以设置断点、查看变量值、使用检查器查看包括 class 实例在内的复合数据结构,并单步执行您的代码——所有这些都是原则上的与您在 PyCharm 等 IDE 中使用的内容非常相似。 Rainer Joswig 的视频调试 CL-HTTP,使用 Clozure Common Lisp、GNU Emacs 和 SLIME (https://vimeo.com/77004324) 演示了所有这些功能,因此您可以看到它是如何在实践中完成的粘液。
与使用 PyCharm 调试相比,我实际上更喜欢 Common Lisp + Slime 的一个功能是,在前者中,您可以 运行 您的程序正常并在出现错误时直接自动进入调试器,而默认情况下,调试器会在出现未捕获异常的地方停止。相比之下,使用 PyCharm 你 运行 你的程序,运行 进入错误,然后用调试器再次启动你的程序并手动设置你的断点或要求 PyCharm 在任何例外。 PyCharm 目前不支持仅在未捕获的异常时自动中断。
我想知道使用 Emacs 和 SLIME 以交互方式调试 Common Lisp 的一些有效方法。
我之前的做法:作为学过C的人,Python使用IDE(VS和PyCharm),我习惯设置断点,添加手表,并进行踩踏。但是当我开始使用 CL 时,我发现调试工作流程根本不同。我没有找到设置断点、单步执行和查看变量如何变化的好方法。
我用的笨办法就是在代码里加"print",一遍又一遍的加运行,效率很低。我知道我们可以在 SLIME 中 "inspect" 变量,但不确定如何以交互方式进行。
我发现了什么: 我最近在 development of a Morse code translator 上看到了这个视频,它展示了如何在 SLIME 中进行交互式调试的完整过程,这已经被非常翔实和有启发性。就好像我们可以 "talk" 给编译器。
我想要的: 我在网上搜索但发现很少有教程演示经验丰富的 Lisper 实际上 开发和调试他们的程序。我渴望学习这样的经验。
- 如何交互调试?
- 有哪些好的做法和技巧?如何添加断点和步骤?
- 调试时您最常使用/发现最有用的快捷方式/工具/工作流程是什么?
您可以做很多事情:
- 您可以跟踪函数调用(请参阅 Common Lisp 中的
TRACE
和UNTRACE
或slime-toggle-trace-fdefinition*
)。这有助于递归调用:您可以在每个级别看到您传递的内容以及它们 return。 - 标准的东西:在地方添加
(format t ...)
。我想,不用评论了。 - 如果代码中断,您将进入调试器。从那里您可以检查堆栈,查看调用了什么以及传递了哪些参数。请参阅@jkiiski link:它有关于它的非常好的信息,包括
(break)
表单,它将充当断点并让您进入调试器。 剧透警报:您可以更改检查器中的值,您可以更改并重新编译您的代码并从(几乎)堆栈中的任何位置重新启动。 - 最后但同样重要的是:要调试宏,您将需要
slime-macroexpand-1
(MACROEXPAND-1
的包装器),甚至更好的C-c M-e
用于宏步进器。
最后一个建议:如果您要进行认真的调试,请在您的文件中包含 (declaim (optimize (debug 3)))
,否则某些 CL 实现倾向于优化堆栈上的调用或使参数不可访问。
使用 Common Lisp 和 Slime,您可以设置断点、查看变量值、使用检查器查看包括 class 实例在内的复合数据结构,并单步执行您的代码——所有这些都是原则上的与您在 PyCharm 等 IDE 中使用的内容非常相似。 Rainer Joswig 的视频调试 CL-HTTP,使用 Clozure Common Lisp、GNU Emacs 和 SLIME (https://vimeo.com/77004324) 演示了所有这些功能,因此您可以看到它是如何在实践中完成的粘液。
与使用 PyCharm 调试相比,我实际上更喜欢 Common Lisp + Slime 的一个功能是,在前者中,您可以 运行 您的程序正常并在出现错误时直接自动进入调试器,而默认情况下,调试器会在出现未捕获异常的地方停止。相比之下,使用 PyCharm 你 运行 你的程序,运行 进入错误,然后用调试器再次启动你的程序并手动设置你的断点或要求 PyCharm 在任何例外。 PyCharm 目前不支持仅在未捕获的异常时自动中断。