[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

5. もう少し複雑な関数

この章では、前の章で学んだことを基礎により複雑な関数を見ていくことにする。 copy-to-buffer 関数は、一つの定義の中で save-excursion を 二回使う方法を示してくれる。一方、insert-buffer 関数の方は interactive 式の中での * の使い方と、or の使い方、 そして、オブジェクトの名前と、その名前のついたオブジェクトとの違いについ て教えてくれる。

5.1 copy-to-buffer の定義  set-bufferget-buffer-create を利用
5.2 insert-buffer の定義  書き込み不可 と or の使い方
5.3 beginning-of-buffer の完全な定義  goto-char, point-min, そし
                                て push-mark を見てみる
5.4 復習  
5.5 &optional 引数の練習問題  &optional の練習問題


5.1 copy-to-buffer の定義

append-to-buffer がどのように動作するかを理解した後であれば、 copy-to-buffer の方も簡単に理解出来る。この関数はテキストを他のバッ ファにコピーする。ただし、そのバッファに付け加えるのではなく、以前あった テキストを置き換えてしまう。copy-to-buffer 関数のコードは append-to-buffer のコードとほぼ同じであるが、erase-buffer を使い、また save-excursion を二回使っている点が違う。 (append-to-buffer の説明については append-to-buffer の定義, を参照。)

copy-to-buffer の本体は次の通りである。

 
...
(interactive "BCopy to buffer: \nr")
  (let ((oldbuf (current-buffer)))
    (save-excursion
      (set-buffer (get-buffer-create buffer))
      (erase-buffer)
      (save-excursion
        (insert-buffer-substring oldbuf start end)))))

このコードは append-to-buffer とそっくりである。 append-to-buffer の定義との違いが現れるのは、テキストがコピーされ るバッファに移ってからである。つまり、この後 copy-to-buffer 関数 では以前の内容を消去してしまう。(これが、「置き換え」と言った意味である。 Emacs ではテキストを置き換える場合、以前の内容をまず消去し、次に新しいテ キストを挿入する。) 以前の内容を消去した後、もう一度 save-excursion が使われる。そして新しいテキストが挿入される。

何故 save-excursion が二回も使われるのか? それを理解するために、 もう一度この関数が何をやっているか見てみよう。

大ざっぱには、copy-to-buffer の本体は次のようになっている。

 
(let (oldbufcurrent-bufferの値にバインド)
  (save-excursion         ; 最初の save-excursionバッファ切替
      (erase-buffer)
      (save-excursion     ; 二番目の save-excursion現在のバッファにoldbufから部分文字列を挿入)))

最初の save-excursion は Emacs にテキストのコピー元のバッファを返 している。これは当たり前のことで、append-to-buffer でも同じような 使われ方をしていたのだった。では何故二番目が必要なのか? 理由は、 insert-buffer-substring が常にポイントを挿入されたリージョンの 最後に移動してしまうからである。二番目の save-excursion があるおかげで、Emacs は挿入されたテキストの最初の位置にポイントを移動す る。大抵の状況では、ユーザーは挿入されたテキストの最初の位置にポイントが あるほうを好むものである。(勿論、copy-to-buffer 関数は終了時に元 居たバッファに戻る---しかし、もしユーザが次にコピー先のバッファに 移ったとすると、ポイントはそのテキストの先頭に移動してくれるというわけで ある。このように、二番目の save-excursion はちょっぴり気の効いた 働きをしてくれるものなのだ。)


5.2 insert-buffer の定義

insert-buffer もまた、バッファに関する関数である。このコマンドは 他のバッファをカレントバッファの中に挿入する。これは append-to-buffercopy-to-buffer と逆である。これらの方 は、カレントバッファからリージョンを取り出して他のバッファにコピー するのであった。

更に、このコードは read-only なバッファに関する interactive の使い方や、オブジェクトの名前と、その名前のついたオブジェクトそのものと の違いの重要性を理解させてくれる。これがそのコードである。

 
(defun insert-buffer (buffer)
  "Insert after point the contents of BUFFER.
Puts mark after the inserted text.
BUFFER may be a buffer or a buffer name."
  (interactive "*bInsert buffer: ")
  (or (bufferp buffer)
      (setq buffer (get-buffer buffer)))
  (let (start end newmark)
    (save-excursion
      (save-excursion
        (set-buffer buffer)
        (setq start (point-min) end (point-max)))
      (insert-buffer-substring buffer start end)
      (setq newmark (point)))
    (push-mark newmark)))

他の関数定義と同様に、テンプレートを使ってこの関数のアウトラインを見るこ とが出来る。

 
(defun insert-buffer (buffer)
  "説明文字列..."
  (interactive "*bInsert buffer: ")
  本体...)

5.2.1 insert-buffer の中のインタラクティブ式  書き込み不可の状態の時の動作
5.2.2 関数 insert-buffer の本体部分  本体には orlet がある
5.2.3 or の代わりに if を使った insert-buffer  or の代わりに if を使う
5.2.4 本体部分の or  
5.2.5 insert-buffer の中の let  二つの save-excursion


5.2.1 insert-buffer の中のインタラクティブ式

insert-buffer ではインタラクティブ宣言の引数には二つの部分がある。 一つはアスタリスク `*' であり、もう一つは `bInsert buffer: ' である。

書き込み不可のバッファ  
インタラクティブ式の中の `b'  


書き込み不可のバッファ

アスタリスクはバッファが read-only---つまり変更出来ないバッファである場合 のためのものである。もし、insert-buffer が read-only なバッファで呼 ばれた場合、エコー領域にその旨を知らせるメッセージが表示され、ビープ音が 鳴るか、画面が明滅する。「あなたはこのバッファに如何なるものも挿入しては いけませんよ」というわけである。アスタリスクの後には、次の引数と分離するた めに改行コードを付ける必要はない。


インタラクティブ式の中の `b'

インタラクティブ式の次の引数は小文字の `b' から始まっている。(これ は append-to-buffer のコードの中のとは違うことに注意。こっちでは 大文字の `B' を使っていたのだった。append-to-buffer の定義, 参照。) 小文字の `b' は Lisp インタプリタに insert-buffer の引数が存 在するバッファないしは、その名前でなければならないことを示している。(大 文字の `B' オプションの方は存在しないバッファであっても良い。) Emacs はプロンプトを出してバッファの名前を要求し、同時にデフォルトのバッ ファも提示してくれる。名前の補完もやってくれる。もし、ここで存在しないバッ ファを指定すると、"No match" というメッセージを受け取る。端末によって はビープ音がするかもしれない。


5.2.2 関数 insert-buffer の本体部分

関数 insert-buffer の本体は、主に二つの部分からなっている。一つは or 式であり、もう一つは let 式である。or 式を使う目 的は、引数 buffer がバッファの名前ではなくちゃんとバッファそのも のにバインドされていることを確認することである。let 式の本体は、 他のバッファをカレントバッファに挿入するコードを含んでいる。

大まかに言って、二つのS式は次のように insert-buffer 関数の中に組 み込まれている。

 
(defun insert-buffer (buffer)
  "説明文字列..."
  (interactive "*bInsert buffer: ")
  (or ...
      ...
  (let (変数リスト)
      letの本体... )

引数 buffer がバッファの名前ではなくバッファそのものにバインドさ れているかを or 式がどのようにして確かめているかを理解するには、 最初に関数 or を理解する必要がある。

が、その前にまずこの部分を if を使って書き直してみたい。そうすれ ばより身近な方法で何がなされているかを見ることが出来るだろう。


5.2.3 or の代わりに if を使った insert-buffer

やるべき仕事は buffer の値がバッファそのものであり、バッファ名で はないことを確認することである。もし値が名前であったら、その名前のついた バッファを持ってこないといけない。

まずあなたが何かのコンファレンスに参加しており、案内係があなた方の名前が 書かれたリストをもってあなたを探している状況を思い浮かべて欲しい。この状 態では案内係はあなた自身ではなく、あなたの名前に「バインド」されている。 しかし、案内係があなたを見つけてあなたの腕を取った時点で、案内係はあなた 自身に「バインド」されたことになる。

Lisp ではこの状況を次のように説明出来る。

 
(if (not (お客をつかまえている))
    (お客を見つけて腕を取る))

我々はこれと同じことをバッファについてやりたいわけである---バッファそのも のでない場合も、バッファを見つけて取って来たいのだ。

bufferp という(バッファの名前ではなく)バッファかどうかを判定して くれる述語を使うと、このコードを次のように書くことが出来る。

 
(if (not (bufferp buffer))              ; if-part
    (setq buffer (get-buffer buffer)))  ; then-part

コメントにもあるが、上の式で、if 式の真偽テストの部分は (not (bufferp buffer)) であり、一方 then-part の部分は (setq buffer (get-buffer buffer)) である。

このテストの中では bufferp 関数は引数がバッファであれば真の値を返 す---しかしバッファの名前であれば偽の値を返す。(bufferp という関 数の名前の最後は `p' で終わっている。以前見たようにこの `p' は、 この関数が述語、つまり、ある性質を持つか否かを判定する関数であることを示 すための工夫として付けられている。 関数に間違った型の引数を与えると, を参照 のこと。)

(bufferp buffer) 式の前には関数 not がある。即ち 真偽テストは次の通りである。

 
(not (bufferp buffer))

not は引数が偽であれば真を返し、偽であれば真を返す関数である。従っ て、もし (bufferp buffer) が真を返せば、not 式が偽を返すし、 偽を返せば真を返す。「真でない」というのは偽ということだし、「偽でない」 というのは真だというわけである。

if は、このテストを使って次のように動作する。変数 buffer の値がバッファの名前ではなく実際にバッファだった場合、真偽テストの結果 は偽である。すると、if 式は then-part を評価しない。これはまとも な動作である。というのは、もし変数 buffer が本当にバッファであれ ば、これに対して特に何もする必要はないからである。

一方で、buffer の値がもしバッファそのものではなくバッファの名前で あったとすると、真偽テストでは真が返り、結果として then-part が評価される。 今の場合、then-part は (setq buffer (get-buffer buffer)) である。 このS式は、その名前のついた実際のバッファを得るために get-buffer 関数を使っている。そして、setq で、変数 buffer の値をバッ ファの名前から実際のバッファそのものに置き換えている。


5.2.4 本体部分の or

insert-buffer 関数で or 式を使う目的は引数 buffer がバッファの名前ではなくバッファそのものにバインドされているかどうかを確 認することにある。前節で、どのようにして if を使ってこの作業をす るかを見た。しかし、insert-buffer 関数では実際は or を使っ ている。この理由を理解するには、or 関数の働きを理解しなければなら ない。

関数 or はいくらでも引数を持つことが出来る。この関数は各引数を順に 評価していき、nil でなかった最初の引数の値を返す。また、これが or の重要な特徴なのだが、この関数は引数で nil 以外の値を返 すものがあった場合、その後の引数はもはや評価しない。

今の場合の or 式は次の通りである。

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

or の最初の引数は S式 (bufferp buffer) である。この式は、 もし buffer がバッファそのものでありバッファの名前ではない場合は、真を返 す。or 式では、この場合、or 式の値として真を返し、その後の 引数は評価されない---我々にはこの方が都合が良い。というのもこの場合には つまり buffer が真のバッファである場合には、この値について何もす る必要がないからである。

一方で、もし (bufferp buffer)nil であれば、それは buffer の値がバッファの名前であるということである。この場合、Lisp インタプリタは or 式の次の引数も評価する。これは (setq buffer (get-buffer buffer)) という式である。この式は値 nil を返 す。これが変数 buffer にセットされた値である---そしてこの値はバッ ファそのものであり、バッファの名前ではない。

以上のことから、シンボル buffer は常に、あるバッファの名前ではな くバッファそのものにバインドされることになる。また、以上の手続きは全てが 必要なことである。というのも、次の行の set-buffer 関数はバッファ に対してしか働かないからである。

ついでだが、or を使った場合、案内係というのは次のように書ける。

 
(or (お客をつかまえている) (お客を見つけて腕を取る))


5.2.5 insert-buffer の中の let

insert-buffer 関数では、変数 buffer がバッファの名前ではな くバッファそのものを表わすことを確認した後には、 let 式が続く。 ここでは三つの変数 start, end, newmark を指定してい る。これらの変数は let 式の内部でのみ使われ、let 式の評価 が終わるまでの間は、一次的に Emacs 内の同じ名前の他の変数は隠されている。

let 式の本体は二つの save-excursion を使っている。まずは、 内側にある方の save-excursion 式を細かく見ていこう。この式は次の 通りである。

 
(save-excursion
  (set-buffer buffer)
  (setq start (point-min) end (point-max)))

S式 (set-buffer buffer) は、Emacs が注目するバッファをテキストが コピー元のバッファに切り替える。このバッファの中で、point-min コ マンド及び、point-max コマンドを使って変数 start と 変数 end に各々バッファの始まりと終わりの位置を設定する。setq を使って、一つのS式で二つの変数を同時に設定する方法についてはもう既に説 明したのだった。setq の最初の引数は二番目の値に、三番目の引数は四 番目の引数の値にセットされる。

外側の save-excursion 式は次の通りである。

 
(save-excursion
  (内側のsave-excursion
     (新しいバッファに移動しstartendをセット)
  (insert-buffer-substring buffer start end)
  (setq newmark (point)))

関数 insert-buffer-substringbuffer から、その中 のstartend で指定されたリージョン内のテキストを、カレ ントバッファの中にコピーする。今の場合、コピー元のバッファ全体が startend の間にあるために、そのバッファ全体が現在編集 中のバッファにコピーされることになる。次に、この時点で挿入されたテキスト の最後にあるポイントの値が、変数 newmark に記録される。

外側の save-excursion の本体が評価された後、ポイントとマークの位 置は元の位置に戻される。

しかしながら、ポイントとマークの位置は新しく挿入されたテキストの最初と最 後にある方が、何かと都合が良い。newmark 変数は挿入されたテキスト の最後の位置を記録する。let 式の最後の行で (push-mark newmark) というS式でマークをこの位置に設定している。(以前のマークの位 置に移動することも可能である。この値はマークリングに保存されていて、 C-u C-SPC で遡ることが出来る。) 一方、ポイントの方は初めから 挿入されたテキストの最初の位置にある。これは insert 関数を呼び出 す前のポイントの位置がここだからである。

完全な let 式は次の通りである。

 
(let (start end newmark)
  (save-excursion
    (save-excursion
      (set-buffer buffer)
      (setq start (point-min) end (point-max)))
    (insert-buffer-substring buffer start end)
    (setq newmark (point)))
  (push-mark newmark))

append-to-buffer 関数の時と同じように、insert-buffer 関数 も let, save-excursion, そして set-buffer を使って いる。それに加えて、この関数は or の使い方の一つも教えてくれてい る。これらの関数は皆大切な部品であり、これから何度でも出てくることだろう。


5.3 beginning-of-buffer の完全な定義

beginning-of-buffer 関数の基本的な構造については、既に議論したこ とがあるのだった。(簡略版 beginning-of-buffer の定義.) このセクションではこの定義の複雑な 部分を説明することにする。

以前説明した通り、引数無しで beginning-of-buffer を呼び出すと、そ の時点でのポイントの位置にマークを設定して、カーソルがバッファの先頭に移 動する。しかしながら、もしこのコマンドが1から10までの数と一緒に呼び出さ れた場合、この関数はバッファ全体を10としてこの数の割合の分を計算し、バッ ファの先頭からその割合の分だけ進んだ位置にカーソルを移動させる。というわ けで、M-< でこのコマンドを呼び出せば、カーソルはバッファの先頭に移 動するし、もし例えば C-u 7 M-< として呼び出せば、カーソルはバッファ 全体の70%分の位置にポイントを移動する。もし引数が10より大きかった場合は バッファの最後に位置に移動する。

beginning-of-buffer 関数は、引数無しで呼び出すことが出来る。つま り、引数は省略可能である。

5.3.1 省略可能な引数  
5.3.2 引数付きで呼び出された場合の beginning-of-buffer  省略可能引数の例
5.3.3 完全版 beginning-of-buffer  完全版


5.3.1 省略可能な引数

特にそうでないと言われない限り、Lisp は、関数定義で引数が指定された関数 はその引数のための値とともに呼ばれるものと思っている。もし、そうでなかっ た場合、エラーが出され、`Wrong number of arguments' というメッセー ジを受け取ることになる。

しかしながら、Lisp の特徴として省略可能引数というものがある。ある キーワード (keyword) を使うと Lisp インタプリタにその引数が 省略可能だと伝えることが出来るのだ。そのキーワードとは &optional で ある。(`optional' の前の `&' もこのキーワードの一部分である。) 関数定義の中でこのキーワード &optional の後に続く引数は、関数が呼 ばれる際に必ずしも値を渡される必要はない。

というわけで、beginning-of-buffer の関数定義の最初の行は次のように なる。

 
(defun beginning-of-buffer (&optional arg)

また、関数定義全体のアウトラインは次のようになっている。

 
(defun beginning-of-buffer (&optional arg)
  "説明文字列..."
  (interactive "P")
  (push-mark)
  (goto-char 
    (もし引数があれば
        どこへ行けばよいか調べる
      そうでなければ次の場所に
      (point-min))))

この関数は simplified-beginning-of-buffer と似ている。違うのは、 interactive 式に "P" が引数として使われていることと、 引数が指定されている場合にカーソルを何処に移動するかを判断する goto-char 関数に続いて if-then-else 式が来ていることである。

interactive 式の中の "P" は、Emacs に、関数に前置 引数を渡すように伝えるものである。前置引数というのは META キーに続いて数をタイプするか、C-u に押してから数をタイ プすることで作ることが出来る。(もし C-u に続いて数を入力しない場合 には、デフォルトとして4が渡される。)

if 式の真偽テストの部分は単純である。単に arg だけだ。もし、 argnil 以外の値を持てば、即ち beginning-of-buffer が引数付きで呼ばれた場合は、真偽テストでは 真が返り、if 式の then-part が評価される。一方、もし beginning-of-buffer が引数とともに呼ばれなかったなら、arg の値は nil になり、if 式の else-part の方が評価される。 else-part は単に point-min であり、この場合には goto-char 式の全体は (goto-char (point-min)) になる。 これは、以前の短縮版 beginning-of-buffer 関数で見た通りである。


5.3.2 引数付きで呼び出された場合の beginning-of-buffer

beginning-of-buffer が引数付きで呼び出された場合は、 goto-char に渡す値を計算する、あるS式が評価される。このS式は、 ちょっと見にはかなり複雑に見える。内部に if 式を含んでいるし、算 数を沢山使っている。実際のコードは次の通りである。

 
(if (> (buffer-size) 10000)
    ;; バッファサイズが大きい場合のオーバーフローを避ける!
    (* (prefix-numeric-value arg) (/ (buffer-size) 10))
  (/
   (+ 10
      (*
       (buffer-size) (prefix-numeric-value arg))) 10))

しかし、他の複雑そうなS式と同様に、これもテンプレートに当てはめてみれば 理解しやすくなる。この場合は、if-then-else 式のテンプレートに当てはめる。 骨組みは次のようになる。

 
(if (バッファが大きいなら
    バッファのサイズを10で割り引数を掛ける
  そうでなければ別の計算をする

この中の if 式の真偽テストはバッファのサイズをチェックしている。 その理由は、Emacs Lisp の version 18 は約8,000,000以下の数値しか扱わない のだが(そんなに大きな数は必要ない)、この計算に従うと、大きなバッファの場 合は Emacs は大き過ぎる数を扱うことになってしまうからだ。コードのコメン トの中に出てくる「オーバーフロー」とは数が大き過ぎることを意味している。

ということで、バッファが大きい場合と、そうでない場合の二つに分けている。

大きなバッファの場合  
小さなバッファの場合  


大きなバッファの場合

beginning-of-buffer の中で内側にある方の if 式はバッファの サイズが10,000文字を越えているかどうかをテストしている。そのために、 >buffer-size という関数を使っている。 その行は次の通りである。

 
(if (> (buffer-size) 10000)

もしバッファが大きい場合は、if 式の then-part が評価される。この 部分を読みやすいよう書き直すと次のようになる。

 
(* 
  (prefix-numeric-value arg) 
  (/ (buffer-size) 10))

このS式は乗法であり、二つの引数を関数 * に渡している。

最初の引数は (prefix-numeric-value arg) である。 interactive 宣言で "P" が指定されている場合、引数は関数に 「未処理の前置引数」(raw prefix argument) として渡され、数値としては渡さ れない。(リストの中では数値である。) 算数で使えるようにするには変換する 必要があり、その仕事を prefix-numeric-value がやっているのである。

二番目の引数は (/ (buffer-size) 10) である。この式は数値としての バッファの値を10で割る。これはバッファサイズの一割にどれだけの文字数が含 まれているかを計算するものだ。(Lisp では / は除法に使われる。 * が乗法に使われるのと同様である。)

乗法の式全体としては、この値に前置引数の値を掛けることになる---こんな感 じだ。

 
(* 数値としての前置引数
   バッファの10分の1の文字数)

(訳註:ここでの文字数とは勿論 ASCIIコードでの話で、日本語等の多バイト文 字が入ると話はまた違ってくる。)

例えば、仮に前置引数が `7' だったとするなら、この10分の1の数に7を掛 けることで、バッファの中の70%の位置が得られることになる。

結局、バッファが大きい場合の goto-char 式全体は次のようになる。

 
(goto-char (* (prefix-numeric-value arg)
              (/ (buffer-size) 10)))

これでカーソルは望む場所に移動してくれる。


小さなバッファの場合

バッファが10,000文字よりも小さかった場合は、ちょっと違った計算方法が取ら れる。さっきの方法でも出来るのだから、こんなことをする必要はないと思うか もしれない。しかし、バッファが小さい場合、初めの方法ではカーソルを望む場 所にきちんと移動してくれない。次に説明する二番目の方法の方がちゃんとした 仕事をしてくれる。

コードは次の通りである。

 
(/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10))

このコードの中で何をしているかは、括弧の中にどのように関数が埋め込まれて いるかを見れば分る。各々の式をそれを含む括弧より深くインデントしてやれば、 より見やすくなる。

 
  (/
   (+ 10
      (*
       (buffer-size)
       (prefix-numeric-value arg)))
   10))

これらの括弧を見ると、もっとも内側にある関数は (prefix-numeric-value arg) であることが分る。これは未処理の 前置引数を数値に変換するものである。この数値は次の式によってバッファサイズと 掛け合わされる。

 
(* (buffer-size) (prefix-numeric-value arg)

この掛け算では、バッファのサイズの値よりも大きな数が生ずる---例えば引数 が7なら7倍大きな数になる。これに10が加えられ、最後にこの大きな数が10で割 られる。こうして得られる値は、バッファのサイズ中の目的とする割合よりも一 文字分だけ大きな数である。

これら一連の操作の結果で得られた数が goto-char に渡され、カーソル がその位置に移動する。


5.3.3 完全版 beginning-of-buffer

ここで、beginning-of-buffer の完全なコードを挙げておく。

 
(defun beginning-of-buffer (&optional arg)
  "Move point to the beginning of the buffer; 
leave mark at previous position.
With arg N, put point N/10 of the way 
from the true beginning.
Don't use this in Lisp programs!
\(goto-char (point-min)) is faster 
and does not set the mark."
  (interactive "P")
  (push-mark)
  (goto-char 
   (if arg
       (if (> (buffer-size) 10000)
           ;; 大きなバッファサイズの場合のオーバーフローを避ける!
           (* (prefix-numeric-value arg)
              (/ (buffer-size) 10))
         (/ (+ 10 (* (buffer-size) 
                     (prefix-numeric-value arg))) 
            10))
     (point-min)))
  (if arg (forward-line 1)))

二つの細かな点を除けば、これまでの議論でこの関数がどう動くかが分るだろう。 細かな点の一つ目は、説明文字列についてであり、二つ目は、この関数の最後の 行に関するものである。

で、一点目だが、説明文字列の中に、あるS式についてのリファレンスがある。

 
\(goto-char (point-min))  

この式の最初の括弧の前に `\' が使われている。この `\' は Lisp インタプリタに対し、このS式は説明として表示されるもので あって、S式として評価されるものではないことを示すものである。

次に二点目だが、beginning-of-buffer コマンドの最後の行は、この関 数が引数とともに呼ばれた場合に、ポイントを次の行の最初に持ってくためのも のである。

 
(if arg (forward-line 1)))

これによって、カーソルはバッファの中の適当な割合の位置の次の行の先頭に移 動する。これが最良の位置であろう。カーソルは少くとも要求された割 合よりかは常に大きい位置に移動するからだ。この動作はちょっと几帳面過ぎる かもしれないが、かと言ってそうしなければ、必ず文句を言う人がいるだろう。


5.4 復習

ここで、この章の幾つかのトピックを手短にまとめておく。

or
引数を順に評価していき、nil でない最初の値を返す。ただし、もしど の引数も nil を返した場合は nil を返す。一言で言うと、引数 の中で真である最初の値を返す。つまり、ある引数が真であるかまたは (or) その他の引数のどれかが真であれば真の値を返す。

and
引数を順に評価していき、どれか一つでも nil があれば、nil を返し、どれも nil で無ければ最後の引数の値を返す。一言で言うと、 全ての引数が真である場合のみ真である値を返す。つまり、ある引数が真であり、 かつ (and) その他の引数も全て真である場合に真の引数を返す。

&optional
関数定義での引数が省略可能であることを示すために使うキーワード。これが あると、その引数がなくともその関数を評価することが出来る。

forward-line
ポイントを次の行の先頭に移動する。1より大きい引数が与えられた場合はその 数の行だけ進む。進めない場合は行けるところまで進み、行くはずではあったが 進めなかった分の行数を値として返す。

erase-buffer
カレントバッファの内容を全て削除する。

bufferp
引数がバッファの場合、t を返す。そうでない場合は nil を返す。


5.5 &optional 引数の練習問題

省略可能な引数を持ち、その引数の数が fill-column の値よりも大きい か小さいかをテストして結果を教えてくれるようなインタラクティブな関数を書 きなさい。ただし、引数なしの場合は56をデフォルトとして使うようにしなさい。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Matsuda Shigeki on April, 10 2002 using texi2html