gpt4 book ai didi

debugging - 为什么 Slime 的调试器不评估所选帧中的这个特定表达式?

转载 作者:行者123 更新时间:2023-12-03 21:04:50 25 4
gpt4 key购买 nike

我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在第 10 章结束时,作者讨论了有用的 break 函数。为了提供背景上下文,他提出了这个有问题的函数:


(defun analyze-profit (price commission-rate)
(let* ((commission (* price commission-rate))
(result
(cond ((> commission 100) 'rich)
((< commission 100) 'poor))))
(format t "~&I predict you will be: ~S"
result)
result))

该函数按预期工作,在 REPL 中使用以下参数调用:
> (analyze-profit 1600 0.15)
I predict you will be: RICH
RICH

> (analyze-profit 3100 0.02)
I predict you will be: POOR
POOR

但是,当 commission 时显示错误的结果。正好是 100:
> (analyze-profit 2000 0.05)
I predict you will be: NIL
NIL
为了调试,作者插入了 break定义上的函数:

(defun analyze-profit-debugging (price commission-rate)
(let* ((commission (* price commission-rate))
(result
(cond ((> commission 100) 'rich)
((< commission 100) 'poor))))
(break "Value of RESULT is ~S" result)
(format t "~&I predict you will be: ~S"
result)
result))
然后他检查了 控制栈在检查局部变量的值时:
enter image description here
我知道调试器是出了名的依赖于实现。
在我的环境(emacs、slime、sbcl)中,我能够在此之后重现类似的东西 great tutorial由@Vindarel 撰写。
将点(光标)放在堆栈上后 0:并按下 e :
Backtrace:
0: (ANALYZE-PROFIT-DEBUGGING 2000 0.05)
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ANALYZE-PROFIT-DEBUGGING 2000 0.05) #<NULL-LEXENV>)
2: (EVAL (ANALYZE-PROFIT-DEBUGGING 2000 0.05))
我能够评估堆栈帧中的表达式。因此,我在 上收到此消息迷你缓冲器 :
Eval in frame (COMMON-LISP-USER)> price
=> 2000 (11 bits, #x7D0, #o3720, #b11111010000)
和:
Eval in frame (COMMON-LISP-USER)> commission-rate
=> 0.05
不幸的是,我无法访问主要问题,即 local variable命名 commission :
Eval in frame (COMMON-LISP-USER)> commission
我期待:
100.0
但我收到一条错误消息:

The variable COMMISSION is unbound. [Condition of typeUNBOUND-VARIABLE]


我仔细检查了拼写。另外,我也试过用 p而不是 e并移动光标。然而,没有任何效果。
如何检查有问题的变量 commission 的值?

最佳答案

如果您导航到调试器中的顶部框架并在该框架上按 Enter,您将看到 commission调试器不知道作为局部变量:

Value of RESULT is NIL
[Condition of type SIMPLE-CONDITION]

Restarts:
0: [CONTINUE] Return from BREAK.
1: [RETRY] Retry SLIME REPL evaluation request.
2: [*ABORT] Return to SLIME's top level.
3: [ABORT] abort thread (#<THREAD "new-repl-thread" RUNNING {1002D65C93}>)

Backtrace:
0: (ANALYZE-PROFIT-DEBUGGING 2000 0.05)
Locals:
COMMISSION-RATE = 0.05
PRICE = 2000
RESULT = NIL
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ANALYZE-PROFIT-DEBUGGING 2000 0.05) #<NULL-LEXENV>)
2: (EVAL (ANALYZE-PROFIT-DEBUGGING 2000 0.05))
--more--
这里的问题是编译器优化掉了一些调试信息。您可以使用 declaim 告诉编译器包含更多调试信息。在文件的开头,或 declare在函数定义中:
(defun analyze-profit-debugging (price commission-rate)
(declare (optimize (debug 3)))
(let* ((commission (* price commission-rate))
(result
(cond ((> commission 100) 'rich)
((< commission 100) 'poor))))
(break "Value of RESULT is ~S" result)
(format t "~&I predict you will be: ~S"
result)
result))
debug 的号码可以是 0、1、2 或 3;更大的数字意味着应该更加重视保留调试信息。
现在在调试器中,在顶部堆栈帧上按回车键显示值 commission直接地:
Backtrace:
0: (ANALYZE-PROFIT-DEBUGGING 2000 0.05)
Locals:
COMMISSION = 100.0
COMMISSION-RATE = 0.05
PRICE = 2000
RESULT = NIL
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ANALYZE-PROFIT-DEBUGGING 2000 0.05) #<NULL-LEXENV>)
2: (EVAL (ANALYZE-PROFIT-DEBUGGING 2000 0.05))
--more--
并且,使用 e顶部堆栈框架上的命令现在按您最初的预期工作:
Eval in frame (COMMON-LISP-USER)> commission
=> 100.0

关于debugging - 为什么 Slime 的调试器不评估所选帧中的这个特定表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67861723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com