5.2.4 insert-buffer 中的 or 表达式

insert-buffer 函数中 or 表达式的目的是确保参数 buffer 绑定到一个缓冲区,而不仅仅是缓冲区的名称。前一节展示了如何使用 if 表达式完成此任务。然而,insert-buffer 函数实际上使用了 or。要理解这一点,有必要了解 or 的工作原理。

一个 or 函数可以有任意数量的参数。它依次评估每个参数,并返回其参数中第一个不是 nil 的值。此外,这是 or 的一个关键特性,即在返回第一个非 nil 值后,它不再评估任何后续参数。

or 表达式如下:

(or (bufferp buffer)
    (setq buffer (get-buffer buffer)))

or 的第一个参数是表达式 (bufferp buffer)。如果缓冲区实际上是一个缓冲区而不仅仅是缓冲区的名称,则此表达式返回 true(一个非 nil 值)。在 or 表达式中,如果是这种情况,or 表达式返回这个 true 值,并且不评估下一个表达式——这对我们来说是可以的,因为如果它确实是一个缓冲区,我们就不希望对 buffer 的值做任何操作。

另一方面,如果 (bufferp buffer) 的值是 nil,那么如果 buffer 的值是缓冲区的名称,Lisp 解释器将评估 or 表达式的下一个元素。这是表达式 (setq buffer (get-buffer buffer))。此表达式返回一个非 nil 值,这是它设置变量 buffer 的值——并且这个值是缓冲区本身,而不是缓冲区的名称。

所有这些的结果是,符号 buffer 总是绑定到缓冲区本身而不是缓冲区的名称。所有这些是必要的,因为后面的一行中的 set-buffer 函数只能与缓冲区本身一起使用,而不能与缓冲区的名称一起使用。

顺便说一下,使用 or,引座员的情况可以写成这样:

(or (holding-on-to-guest) (find-and-take-arm-of-guest))