Elisp中临时变量的有效范围

Vim、Emacs配置和使用
回复
头像
sweating
帖子: 200
注册时间: 2009-02-07 18:01
送出感谢: 0
接收感谢: 0

Elisp中临时变量的有效范围

#1

帖子 sweating » 2011-04-01 13:35

最近,写一个类似于define-key的函数,但是针对的不是(kbd "C-z")之类的按键,而是将aaa,bbb,xxx这样的按键能够被绑定在函数上,并且当按下类似于aab,aac,aaf之类的按键会将按下的字符自动上屏

这是最开始的函数(现在并不考虑同时设置了aaa,dda,这种有着相同结尾的按键,本来想的是先实现了只有一个函数的,然后再看describe-key是如何实现的,作继承(或者说是包含))

(defun redefined-key (key-map keys func)
(define-key key-map (string (car (last (string-to-list keys))))
(lambda() (interactive)
(insert (car (last (string-to-list keys))))
(if (looking-back keys) ((lambda() (delete-backward-char (string-width keys))) (funcall func)) (message "default insert")))))

(redefined-key emacs-lisp-mode-map "aaa" (lambda() (move-beginning-of-line nil)))
按下a键,返回
last: Symbol's value as variable is void: keys

于是使用let来寻找是哪个keys没有值,发现是下面的
(insert (car (last (string-to-list keys))))
的keys没有被赋值
也就是说,如果在一个函数里面,所有的临时变量的symbol全部无法访问(因为用let改写依然没有赋值)

虽然如此,但是我居然抱有着这样的一种期望:只有let 和 lambda出现的临时变量是不能访问的,而set/setq是可以的
于是
(defun redefined-key (key-map keys func)
(setq chr (car (last (string-to-list keys))))
(setq fc func)
(define-key key-map (string (car (last (string-to-list keys)))) (lambda()
(interactive)
(insert chr)
(if (looking-back keys) ((lambda()
(delete-backward-char (string-width ks))
(funcall fc)
))
(message "default insert")))))

(redefined-key emacs-lisp-mode-map "aaa" (lambda() (move-beginning-of-line nil)))
(redefined-key emacs-lisp-mode-map "eee" (lambda() (move-end-of-line nil)))
结果我按下a的时候出现的是e
因为setq把symbol设置成全局变量

像这样的函数中不能访问一些临时变量的情况其实其他的地方(perl)中也有,perl的情况
sub foo{
aaaa=shift;
......
sub{
....
aaaa;#aaaa还活着
....
sub{
....
aaaa;#aaaa没有值了
.....
}}}
但是这个问题不是不能解决的,比如我们可以将第二个sub 中写bbbb=aaaa;第三个sub中用bbbb
但是elisp中第二个函数定义就不可以了,掀桌

然后考虑的是,能不能像bash(day_$i),perl那样动态生成symbol
于是寻找能够动态生成symbol的函数
没有,没有,没有,没有能够动态生成symbol的函数,再掀桌

所以说
1. elisp中,(lambda()....)有时候不认前面所有的一些临时变量的
这里说有时候的原因是if (looking-back keys)是认得keys的
2. elisp中,我没有找到动态从string或者int生成symbol的函数
3. 终于了解到为什么有人写了用scheme配置emacs的程序了,如果用elisp的话,想要返回一个匿名函数很可能会遇到各种各样的问题
头像
sweating
帖子: 200
注册时间: 2009-02-07 18:01
送出感谢: 0
接收感谢: 0

Re: Elisp中临时变量的有效范围

#2

帖子 sweating » 2011-04-03 12:31

问题解决
lexical-let(require 'cl),make-symbol,intern,#1=#:
回复

回到 “Vim和Emacs”