Emacs Lisp嵌套函数-空变量错误 [英] Emacs Lisp nested function - void-variable error

查看:102
本文介绍了Emacs Lisp嵌套函数-空变量错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像这样一个计时器:

I want to make a timer, like this one:

(defun dumb (y)
  (defun P () (print y))
  (run-with-timer 0 5 'P))

(dumb 5)

然后Emacs给我这个错误:

Then Emacs gives me this error:

Error running timer `P': (void-variable y)

我想问题是在(defun P()(print y))行,未评估变量 y ,因此当我运行(哑5),函数 P 尝试打印 y ,但未定义,而不是文字 5 。但我不知道如何解决。

I guess the problem is that in the (defun P () (print y)) line, the variable y is not evaluated, so when I run (dumb 5), the function P tries to print y, which is undefined, instead of a literal 5. But I don't know how to solve it. Any idea?

推荐答案

首先, defun 是用于在全球范围。您只需要使用lambda表单构建一个匿名函数即可。

First, defun is for defining functions in the global scope. You only need to build an anonymous function instead, with a lambda form.

第二, y 仅绑定到 dumb 正在执行时的值(动态范围)。用 run-with-timer 注册该函数是异步的,并立即退出。调用回调时,不再绑定 y

Second, y is only bound to a value while dumb is being executed (dynamic extent). Registering the function with run-with-timer is asynchronous and exits immediately. When your callback is called, y is not bound anymore.

您可以激活词汇绑定在当前缓冲区中,带有文件局部变量:

You can activate lexical binding in you current buffer with a file-local variable:

;;; -*- lexical-binding: t -*-
(defun dumb (y)
  (run-with-timer 0 5 (lambda () (print y))))

或者,当词法绑定 nil时,您可以使用当前绑定值 y 来构建 lambda表单:

Alternatively, when lexical-binding is nil, you can "build" the lambda form with the currently bound value of y injected in it:

(defun dumb (y)
  (run-with-timer 0 5 `(lambda () (print ,y))))

这篇关于Emacs Lisp嵌套函数-空变量错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆