12.6 定义变量的建议

当你定义的变量的 value 是函数,或者一个函数列表时,你最好分别用以 '-function' 或 '-functions' 结尾的变量名来定义。

以下还有一些命名建议:

'...-hook' 这个变量通常是一个普通的 hook

'...-function' 这个变量的值是一个函数

'...-functions' 这个变量的值是一个函数列表

'...-form’ 这个变量的值是一个表达式

'...-forms' 这个变量的值是一个表达式列表

'...-predicate' 这个变量的值是一个谓词函数

'...-flag' 这个变量的值是布尔类型

'...-program' 这个变量的值是程序名称

'...-command' 这个变量的值是一整个shell命令

'...-switches' 这个变量的值指明了命令的可选项

'prefix--...' 这个变量主要在内部使用,而且定义在 prefix.el 文件内

'...-internal' 这个变量主要在内部使用,而且定义在 C code 内

当你定义一个变量时,你需要思考你是否需要将其标记为安全变量(或者有风险的变量);详情查阅文件局部变量。

当定义并初始化一个有复杂值的变量时(比如按键绑定),最好的方式是将整个求值过程放在 defvar 内部,比如:

(defvar my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-c\C-a" my-command)
    ...
    map)
  docstring)

这个方法有几个好处,首先当加载文件时,如果用户推出,那么这个变量要么未完成初始化,要么已经正确的初始化了,而绝不会出现中间的状态。如果这个变量没有被初始化,那么重新加载这个文件,便可以让变量正确的初始化。其次,如果这个变量已经初始化了,那么重新加载文件并不会修改它;当用户已经运行过hook来改变一些配置(比如按键重新绑定)时,这个好处非常重要。最后,使用 C-M-x 运行 defvar 特殊式会完全重新初始化 map。

不过,将这个么多的代码放在 defvar 内有一个缺点:它会把 docstring 的位置拖后很多。这里有一个方法可以应对:

(defvar my-mode-map nil
  docstring)
(unless my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key-map "\C-c\C-a" 'my-command)
    ...
    (setq my-mode-map map)))

这样就和之前的方法有一样的优点,不过如果你想完全重新初始化变量,你要多按一次 C-M-x。

最后更新于