我是ELISP和LISP的新手。这是一些示例代码:
(setq number 2)
(* 8 number)
在lisp交互模式下,我可以在一行的末尾使用组合键控制+ j,它应该内联评估它。如果我尝试在第二行代码(* 2 number)
执行此操作,则会收到错误消息:
Debugger entered--Lisp error: (void-variable number)
(* 8 number)
我的假设是number
未注册为具有值。如果我在第一行代码(setq number 2)
上执行control + j,那么我可以在第二行上使用control + j就好了。
我的问题是,我的假设是因为没有评估第一个值,第二个值不正确吗?而且,是否有更好的方法在交互模式下注册这些值,而不是逐行注册?我假设当这个应用程序正常运行时,除了在Emacs内部之外,这不是问题,只是在Emacs内部即时评估代码时的问题。
答案 0 :(得分:4)
Elisp(以及像Common Lisp这样的其他Lisps)通常会评估表单。在这种情况下,您有两个表单,对应于您的两行。
(setq number 2)
(* 8 number)
组合C-j
专门评估(并打印)表单。另一个有用的选项,我倾向于使用C-x C-e
来评估光标前面的形式。也就是说,如果您想评估(setq number 2)
,则可以将光标放在)
之后。
要评估整个缓冲区,您可以使用M-x eval-buffer
。这将评估您在当前缓冲区中编写的所有内容。例如,您的number
变量将成为"已知"之后。
此外,this提问线程可能有助于阅读。
答案 1 :(得分:4)
是的,你是对的。正如另一个答案所说,lisps评估'形式'通常有两种操作模式:
Emacs和其他Lisp环境通常也支持将一个或多个表单指向文件(或缓冲区)并说“评估”。这就存在一个问题,即可能不清楚究竟是什么评估以及以什么顺序。有些系统会跟踪这一点并让您说,例如,评估缓冲区中所有已更改的顶级表单'。我认为Emacs本身没有这个。
三个交互式Emacs功能可以帮助您:
eval-region
将评估该地区的表单; eval-buffer
将评估整个缓冲区(就像您选择了整个缓冲区并说eval-region
); ielm
(可能不存在于所有邮件中,但我认为最近的任何内容)会为您提供一个交互式的elisp提示符,您可以在其中键入表单进行评估。答案 2 :(得分:2)
要完成答案(是的,您必须M-x eval-buffer
才能运行整个lisp代码),我们可以使用变量number
进行一些操作。
在Lisp中number
表示存储的值,而'number
表示变量“name”(或符号)。
例如,setq
只是set quoted
的快捷方式,因为我们希望影响符号的值。这3行当量:
(setq number 8)
(set 'number 8)
(set (quote number) 8)
然后你可以玩
(message (format "Result is %s" (* 8 number)))
(message (format "Result is %s" '(* 8 number)))
(message (format "Result is %s" `(* 8 ,number)))
打印哪些:
Result is 64
Result is (* 8 number)
Result is (* 8 8)
评论:
(* 8 number) : do the computation, you get a number
'(* 8 number) : keep unevaluated form
`(* 8 ,number) : evaluate number (notice the , char) then keep in an unevaluated form
最后一件事,将值解除绑定到符号只需使用
(makunbound 'number)
如果您现在尝试
(message (format "Result is %s" (* 8 number)))
您将收到错误消息:
Symbol’s value as variable is void: number
确认符号number
不再绑定到任何值。