insert-buffer or の代わりに if を使用する場合
¶取り組むべき課題は、buffer
の値がバッファ名ではなく、バッファそのものであることを確実にすることである。もしその値が名前である場合は、バッファ自体を取得しなければならない。
カンファレンスで、案内係があなたの名前が書かれたリストを手に歩き回り、あなたを探している様子を想像してみてください。案内係はあなたの名前に縛られているのであって、あなたに縛られているわけではありません。しかし、案内係があなたを見つけ、腕を取ったとき、案内係はあなたと結ばれるのです。
Lispでは、このような状況を次のように表現するかもしれません。
(if (not (holding-on-to-guest))
(find-and-take-arm-of-guest))
バッファについても同様のことをしたいと考えています。バッファ自体を持っていない場合は、それを取得したいということです。
バッファの有無を判定する(名前ではなく)bufferpという述語を用いて、次のようにコードを記述できます。
(if (not (bufferp buffer)) ; if-part (setq buffer (get-buffer buffer))) ; then-part
ここで、if 式の真偽判定は (not (bufferp buffer)) であり、then 部分は式 (setq buffer (get-buffer buffer)) です。
このテストでは、関数 bufferp は、引数がバッファであれば true
を返しますが、引数がバッファ名であれば false を返します。(関数名 bufferp
の最後の文字は ‘p’ です。前述の通り、このような
‘p’
の用法は、その関数が述語であることを示す慣習であり、ここでの述語とは、その関数がある性質が真か偽かを判定することを意味する用語です。不適切な型のオブジェクトを引数として使用する
を参照してください。)
関数 not が式 (bufferp
buffer) よりも前にあるため、真偽判定は次のようになります。
(not (bufferp buffer))
not は、引数が false であれば true を、true であれば false
を返す関数です。したがって、(bufferp buffer) が true を返す場合、not の式は false を返し、その逆も同様です。
このテストを用いると、if 式は次のように動作します。変数 buffer の値が実際には名前ではなくバッファである場合、真偽判定は false を返し、if 式は then 部を評価しません。buffer
変数が実際にバッファである場合に特別な処理を行う必要はないため、これで問題ありません。
一方、buffer の値がバッファそのものではなくバッファ名である場合、真偽判定は true
を返し、式の then 部分が評価されます。この場合、then 部分は (setq buffer
(get-buffer buffer)) となります。この式では get-buffer
関数を使用して、名前を指定して実際のバッファそのものを返します。その後、setq が変数 buffer にバッファ自体の値を代入し、それまでの値(バッファ名)を上書きします。