Emacs Lisp嵌套函数 - void-variable错误

时间:2015-10-28 04:29:47

标签: elisp emacs24

我想制作一个计时器,就像这个:

#include <iostream>
#include <functional>

void foo(const std::function<int(int)>& f)
{
  std::cout << f(3) << std::endl;
}

int add(int x, int y)
{
  return x + y;
}

int main()
{
  std::function<int(int)> f_binded = std::bind(add, 4, std::placeholders::_1);
  foo(f_binded);
}

然后Emacs给了我这个错误:

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

(dumb 5)

我想问题是在Error running timer `P': (void-variable y) 行中,变量(defun P () (print y))未被评估,因此当我运行y时,函数(dumb 5)会尝试打印{ {1}},这是未定义的,而不是文字P。但我不知道如何解决它。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

首先,defun用于定义全局范围内的函数。您只需要使用lambda表单构建一个匿名函数。

其次,y仅在执行dumb时绑定到一个值(动态范围)。向run-with-timer注册该函数是异步的,并立即退出。当您的回调被调用时,y不再受约束。

您可以使用文件本地变量激活当前缓冲区中的lexical binding

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

或者,当lexical-bindingnil时,您可以“构建”lambda表单,其中注入了当前绑定值y

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

答案 1 :(得分:1)

解决此问题的另一种方法是将额外参数传递给run-with-timer

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

run-with-timer在调用函数后接受任意数量的参数,并且这些参数将在计时器触发时传递。