调试器即 REPL,REPL 即调试器:一种新的 Debugger 使用方式
文章的核心观点是,将调试器与 REPL 结合使用,能显著提升调试效率。作者通过 IntelliJ IDEA 的“Run to Cursor”和“Quick Evaluate Expression”两个特性,展示了如何将调试器转化为更强大的交互式环境。这种方法允许开发者在程序执行过程中,快速跳转到特定位置,并即时评估新的表达式,从而实现类似 REPL 的体验。作者强调了这种方式的优势,包括基于 2D 文本的交互、无缝评估新代码以及利用断点访问局部变量。
调试器即 REPL,REPL 即调试器 Mar 25, 2025
我_热爱_调试器! 上一次我认真使用调试器大约是在 2017 年左右,那时我还在用 Kotlin 编程。 自那以后,我转而使用原生代码,但遗憾的是,gdb
和 lldb
对我几乎没有帮助。 这是因为它们仅仅是“调试器”,但我需要的是一个 REPL,以及一个调试器,合二为一。 在本文中,我将展示一种更高效的使用调试器作为 REPL 的方法。
这个技巧归结为两个 IntelliJ IDEA 的特性:Run to Cursor 和 Quick Evaluate Expression。
第一个特性,Run to Cursor,恢复程序的运行,直到到达光标所在的那一行。 它是 stepping into, over, 和 out 等原始调试器特性的声明式替代方案 —— 你不再需要告诉调试器如何执行每一步,而是直接告诉它你想去哪里:
第二个特性,Quick Evaluate Expression,在当前堆栈帧的上下文中计算选定的表达式。 关键的是,这不一定是预先存在的表达式,你可以输入新的东西并计算它!
Run to Cursor 设置了有趣的上下文,而 Quick Evaluate 允许你四处探索。 这两个特性完全改变了我使用调试器的方式 —— 我不再单步执行程序并观察它,而是在执行的各个有趣点之间快速切换并进行实验。
调试器和 REPL 的作者们,请注意工作流的以下特点:
- 没有任何提示符。 交互的媒介是 2D 程序文本,而不是 1D 命令行。 这是一个
vi
界面,而不是ed
界面。 - 从调试器的角度来看,我们支持在上下文中无缝评估_新的_程序文本。 在输入新文本时,你将获得完整的代码补全体验。 我还没有大量使用它,但应该也可以使用更改后的代码进行_重新加载_。
- 从 REPL 的角度来看,你需要断点。 顶层上下文很少有趣! 你需要能够将自己置于应用程序的“中间”,在那里你可以访问所有的局部变量。 调试器通过设置断点来实现这一点,但是点击边缘(或者更糟,以文本方式输入
file:line:column
)的 UI 非常糟糕。 任何编辑器中都有一个非常好的指点设备 —— 光标。 只要让程序执行到那个点就可以了!