为什么 Slime 的调试器不在选定的帧中评估这个特定的表达式?
Why Slime's debugger is not evaluating this specific expression in the selected frame?
我正在尝试通过 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))
然后他检查控制堆栈,同时检查局部变量的值:
我知道调试器非常依赖于实现。
在我的环境(emacs、slime、sbcl)中,我能够在@Vindarel 写的 great tutorial 之后重现类似的东西。
将点(光标)放入堆栈 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
不幸的是,我无法访问名为 commission
:
的 local variable
的主要问题
Eval in frame (COMMON-LISP-USER)> commission
我期待:
100.0
但我收到一条错误消息:
The variable COMMISSION is unbound. [Condition of type
UNBOUND-VARIABLE]
我仔细检查了拼写。此外,我还尝试使用 p
而不是 e
并四处移动光标。然而,没有任何效果。
如何检查有问题的变量的值 commission
?
如果您导航到调试器的顶部框架并在该框架上按回车键,您将看到调试器不知道 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
我正在尝试通过 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))
然后他检查控制堆栈,同时检查局部变量的值:
我知道调试器非常依赖于实现。
在我的环境(emacs、slime、sbcl)中,我能够在@Vindarel 写的 great tutorial 之后重现类似的东西。
将点(光标)放入堆栈 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
不幸的是,我无法访问名为 commission
:
local variable
的主要问题
Eval in frame (COMMON-LISP-USER)> commission
我期待:
100.0
但我收到一条错误消息:
The variable COMMISSION is unbound. [Condition of type UNBOUND-VARIABLE]
我仔细检查了拼写。此外,我还尝试使用 p
而不是 e
并四处移动光标。然而,没有任何效果。
如何检查有问题的变量的值 commission
?
如果您导航到调试器的顶部框架并在该框架上按回车键,您将看到调试器不知道 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