[每当出现错误时,Sly都会显示重新启动和回溯。我见过互联网上的人,他们的回溯是可读的,这些回溯是明智的函数调用。当我在副本中输入(fun duf)
时,我得到的是这样的内容:
Backtrace:
0: ((LAMBDA ()))
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FUN DUF) #<NULL-LEXENV>)
2: (EVAL (FUN DUF))
3: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
4: (SLYNK::CALL-WITH-RETRY-RESTART "Retry SLY mREPL evaluation request." #<CLOSURE (LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1) {100308AA1B}>)
5: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
6: ((LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER))
7: (SLYNK::CALL-WITH-BINDINGS ((*PACKAGE* . #<PACKAGE "COMMON-LISP-USER">) (* . 13) (** . 10) (***) (/ 13) (// 10) ...) #<CLOSURE (LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER) {100308A68B}>)
8: (SLYNK-MREPL::MREPL-EVAL-1 #<SLYNK-MREPL::MREPL mrepl-2-2> "(fun duf)")
9: (SLYNK-MREPL::MREPL-EVAL #<SLYNK-MREPL::MREPL mrepl-2-2> "(fun duf)")
...
还有更多。这使我无法调试代码。我尝试过:(declaim (optimize (debug 3)))
,但没有区别。同样,即使调用是一个实际函数,输出也不是更好。我已经尝试了gnuclisp和sbcl。
[我认为您认为您看到的很多东西都是垃圾,只是因为您还不知道它是什么。
*
至***
绑定到最后的结果(REPL的便捷功能)。call-with-listener
可能确定输出应该转到Sly。retry
重新启动。如果您在调试器中调用Retry
重新启动,则将在此帧中转移控制权。call-with-…
命名约定。eval
对其进行评估。eval
的实现。这里没什么可看的,因为eval
首先要做的是评估duf
,这失败了。
计算机不知道您要调试的当前堆栈上下文的哪一部分。因此,它[[必须向您显示整个回溯,否则将使那些对他们感兴趣的信息被隐瞒的人们感到痛苦。
您需要学习的是识别您感兴趣的东西从哪里开始。在这里,所有Slynk的东西(显然是?)都在您的上下文之下,因此您实际上只需要查看零件,直到第一行eval
。在这种情况下,这只是第一行,这很有意义,因为您输入的行只会在第一次查找时失败。对于Sly开发人员而言,那些较低的堆栈框架可能很有趣。当然,在更现实的情况下,有些实现的回溯比其他实现更清晰。那不是Sly可以做的事情。它的作用是为您提供从回溯中的任何行跳至相应源文件位置(如果可用)的选项(在SLIME中为v
(视图),不了解Sly)。您可以做很多事情,例如G。检查本地绑定/变量/参数,并调用重新启动。看看手册。