[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本章では、前章で学んだことをもとに、多少複雑な関数を見てみよう。 関数copy-to-buffer
では、1つの定義内で式save-excursion
を 2つ使う方法を、関数insert-buffer
では、 interactive
式でのアスタリスクの使い方とor
の使い方を、 名前と名前が参照するオブジェクトとの重要な違いを示す。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
copy-to-buffer
の定義 (2004/08/05)
copy-to-buffer
の定義"へのコメント(無し)
append-to-buffer
の動作を理解していれば、 copy-to-buffer
を理解するのは容易である。 この関数はテキストをバッファにコピーするが、 指定したバッファに追加するのではなく、指定バッファの内容を書き換える。 関数copy-to-buffer
のコードは、append-to-buffer
のコードと ほぼ同じであるが、erase-buffer
ともう1つsave-excursion
を使う (append-to-buffer
の説明は、 See 節 4.4 append-to-buffer
の定義 (2004/08/05))。
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では、テキストを書き換えるには、既存のテキストを削除してから、 新たなテキストを挿入する)。 バッファの既存の内容を削除したあと、 2つめのsave-excursion
を使い、新たなテキストを挿入する。
なぜsave-excursion
を2つ使うのだろうか? 関数の動作を見直してみよう。
copy-to-buffer
の本体の概略はつぎのとおりである。
(let ( |
最初のsave-excursion
で、Emacsは、テキストのコピーもとのバッファに 戻ることができる。 これはappend-to-buffer
での用法と同じであり、明らかであろう。 では、2つめは何のためであろう? insert-buffer-substring
は、つねに、 挿入したリージョンの最後にポイントを置く。 2番目のsave-excursion
により、 Emacsは挿入したテキストの先頭にポイントを置くことになる。 多くの場合、ユーザーは、挿入したテキストの先頭にポイントがあることを好む (もちろん、関数copy-to-buffer
が完了するともとのバッファに戻る。 しかし、ユーザーがコピー先のバッファに切り替えると、 ポイントはテキストの先頭にある。 つまり、このために2番目のsave-excursion
がある)。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
insert-buffer
の定義 (2004/08/05)
insert-buffer
の定義"へのコメント(無し)
insert-buffer
もバッファに関連した関数である。 このコマンドは、別のバッファからカレントバッファへコピーする。 カレントバッファのテキストのリージョンを別のバッファへコピーする append-to-buffer
やcopy-to-buffer
とは逆向きである。
また、このコードでは、読み出し専用(read-only)のバッファでの interactive
の使い方と、オブジェクトの名前と名前が参照する オブジェクトとの重要な違いを示す。
insert-buffer
のソースコード5.2.1 insert-buffer
のinteractive
式When you can read, but not write. 5.2.2 関数 insert-buffer
の本体 (2004/08/05)The body has an or
and alet
.5.2.3 or
のかわりにif
を使ったinsert-buffer
(2004/08/05)Using an if
instead of anor
.5.2.4 or
の本体 (2004/08/05)How the or
expression works.5.2.5 insert-buffer
のlet
式 (2004/08/05)Two save-excursion
expressions.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
insert-buffer
のソースコードinsert-buffer
のソースコード"へのコメント(無し)
コードはつぎのとおりである。
(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: ") 本体...) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
insert-buffer
のinteractive
式insert-buffer
のinteractive
式"へのコメント(無し)
insert-buffer
では、interactive
の引数には、 アスタリスク`*'と`bInsert buffer: 'の2つの部分がある。
読み出し専用バッファ When a buffer cannot be modified. interactive
式の`b'An existing buffer or else its name.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
アスタリスクは、読み出し専用バッファ、つまり、 変更できないバッファに対処するためである。 読み出し専用のバッファにinsert-buffer
を使うと、 読み出し専用である旨のメッセージがエコー領域に表示され、 端末のベルが鳴るか点滅する。 カレントバッファには挿入できないのである。 アスタリスクのあとにはつぎの部分との区切りに改行は必要ない。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
interactive
式の`b'interactive
式の`b'"へのコメント(無し)
interactive
式の引数の2番目の部分は、小文字の`b'で始まっている (大文字の`B'で始まるappend-to-buffer
のコードと異なる See 節 4.4 append-to-buffer
の定義 (2004/08/05))。 小文字の`b'は、insert-buffer
の引数は既存のバッファであるか バッファ名であることをLispインタープリタに指示する (大文字の`B'では、バッファが存在しない場合も許す)。 Emacsは、デフォルトのバッファを提示してバッファ名を問い合わせ、 名前の補完も行う。 バッファが存在しないと、メッセージ「No match(一致するものがない)」を表示して 端末のベルを鳴らす。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
insert-buffer
の本体 (2004/08/05)
insert-buffer
の本体"へのコメント(無し)
関数insert-buffer
の本体には、2つの主要な部分、 or
式とlet
式がある。 or
式の目的は、引数buffer
がバッファの名前ではなく、 バッファに束縛されていることを保証することである。 let
式の本体は、 別のバッファからカレントバッファにコピーするコードである。
関数insert-buffer
の2つの式の概略はつぎのとおりである。
(defun insert-buffer (buffer)
"説明文..."
(interactive "*bInsert buffer: ")
(or ...
...
(let (変数リスト)
|
or
式により、どのようにして引数buffer
にバッファ名ではなく バッファが束縛されることが保証されるのかを理解するには、 まず、関数or
を理解する必要がある。
そのまえに、関数の最初の部分をif
で書き換えて、 すでによく知っている方法で考えてみよう。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
or
のかわりにif
を使ったinsert-buffer
(2004/08/05)
or
のかわりにif
を使ったinsert-buffer
"へのコメント(無し)
必要なことは、buffer
の値をバッファ名ではなく バッファそのものとすることである。 値が名前の場合には、対応するバッファそのものを取得する必要がある。
読者の名前が記された名簿を持って、会議場で受け付け係が読者を探している 場面を想像してほしい。 このとき受け付け係には、読者自身ではなく読者の名前が「束縛」されている。 受け付け係が読者を探しあてて読者の腕をとると、 受け付け係には読者が「束縛」される。
Lispでは、このような状況をつぎのように書ける。
(if (not (招待客の腕をとっている)) (招待客を探し、腕をとる)) |
バッファについても同じことをしたいのである。 バッファそのものを取得していなければ、それを取得したいのである。
(名前ではなく)バッファそのものを持っているかどうかを調べる 述語bufferp
を用いれば、つぎのようなコードが書ける。
(if (not (bufferp buffer)) ; 判定条件 (setq buffer (get-buffer buffer))) ; 真の場合の動作 |
ここで、if
式の判定条件は(not (bufferp buffer))
であり、 真の場合の動作は、式(setq buffer (get-buffer buffer))
である。
判定条件では、引数がバッファならば関数bufferp
は真を返すが、 引数がバッファ名の場合には偽を返す (関数名bufferp
の最後の文字は`p'である。 すでに説明したように、`p'をそのように使うのは、 関数が述語(predicate)であることを意味する慣習である。 また、述語とは、ある性質が真であるか偽であるかを調べる関数であった。 See 節 1.8.4 引数に誤った型のオブジェクトを指定 (2004/01/17))。
式(bufferp buffer)
のまえには関数not
があり、 判定条件はつぎのとおりである。
(not (bufferp buffer)) |
not
は、引数が偽の場合には真を、真の場合には偽を返す関数である。 したがって、(bufferp buffer)
が真ならばnot
式は偽を返し、 偽ならば真を返す。 「not 真」は偽であり、「not 偽」は真である。
この判定条件を使うと、if
式はつぎのように動作する。 変数buffer
の値がバッファ名ではなく実際のバッファであれば、 判定条件は偽となり、if
式の真の場合の動作は評価されない。 変数buffer
が実際のバッファであれば何もする必要はないので、 これでよい。
一方、buffer
の値がバッファそのものではなくバッファ名の場合には、 判定条件は真を返し、真の場合の動作が評価される。 ここでは、真の場合の動作は(setq buffer (get-buffer buffer))
である。 この式では、バッファ名を与えると実際のバッファそのものを 返す関数get-buffer
を使う。 setq
により、変数buffer
にバッファそのものを設定し、 (バッファ名であった)まえの値を置き換える。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
or
の本体 (2004/08/05)
or
の本体"へのコメント(無し)
関数insert-buffer
でのor
式の目的は、 引数buffer
にバッファ名ではなくバッファが束縛されていることを 保証することである。 上の節では、if
式を用いてこれを行う方法を示したが、 関数insert-buffer
では実際にはor
を使っている。 これを理解するには、or
の動作を理解する必要がある。
関数or
は、任意個数の引数を取る。 各引数を順番に評価し、nil
以外の値を返した最初の引数の値を返す。 さらに、nil
以外の値が初めて返されると、 それよりうしろの引数をいっさい評価しないのも、or
の重要な機能である。
or
式はつぎのようになる。
(or (bufferp buffer) (setq buffer (get-buffer buffer))) |
or
の最初の引数は、式(bufferp buffer)
である。 この式は、バッファが名前ではなく実際のバッファであるときには 真(nil
以外の値)を返す。 or
式では、この場合にはor
式は真の値を返し、 そのつぎの式は評価しない。 buffer
の値が実際のバッファであれば何もする必要はないので、 これでよい。
一方、buffer
の値がバッファ名であると、 (bufferp buffer)
の値はnil
であり、 Lispインタープリタはor
式のつぎの要素を評価する。 つまり、式(setq buffer (get-buffer buffer))
を評価する。 この式は、nil
以外の値、つまり、変数buffer
に設定した値であり、 バッファ名ではなくバッファそのものである。
以上の効果をまとめると、シンボルbuffer
には、つねに、 バッファ名ではなくバッファそのものが束縛されるのである。 後続行の関数set-buffer
はバッファ名ではなくバッファそのものしか 扱えないので、以上の処理が必要なのである。
なお、or
を使えば、受け付け係の例はつぎのように書ける。
(or (招待客の腕をとっている) (招待客を探し腕をとる)) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
insert-buffer
のlet
式 (2004/08/05)
insert-buffer
のlet
式"へのコメント(無し)
変数buffer
がバッファ名ではなくバッファそのものを参照することを 保証したあと、関数insert-buffer
はlet
式に進む。 ここには、3つのローカル変数、start
、end
、newmark
があり、 それぞれを初期値nil
に束縛する。 これらの変数はlet
内部の残りの部分で使われ、 let
が終わるまでEmacsの同じ名前の変数の出現を一時的に隠す。
let
の本体には2つのsave-excursion
がある。 まず、内側のsave-excursion
を詳しく見てみよう。 その式はつぎのとおりである。
(save-excursion (set-buffer buffer) (setq start (point-min) end (point-max))) |
式(set-buffer buffer)
は、Emacsの注意をカレントバッファから テキストのコピーもとのバッファに向ける。 そのバッファにて、コマンドpoint-min
とpoint-max
を用いて バッファの先頭と最後を変数start
とend
に設定する。 ここでは、setq
により、1つの式で2つの変数に値を設定する方法も 示している。 setq
の最初の引数には第2引数の値が、第3引数には第4引数の値が設定される。
内側のsave-excursion
の本体を終了すると、 save-excursion
はもとのバッファに戻すが、 start
とend
には、 テキストのコピーもとのバッファの先頭と最後の値が設定されたままである。
外側のsave-excursion
式の概要はつぎのとおりである。
(save-excursion (内側の式 |
関数insert-buffer-substring
は、 バッファbuffer
の始めstart
から終わりend
までのリージョンの テキストをカレントバッファにコピーする。 start
とend
のあいだは2番目のバッファ全体であるので、 2番目のバッファ全体が読者が編集しているバッファにコピーされる。 続いて、挿入したテキストの最後にあるポイントを変数newmark
に記録する。
外側のsave-excursion
の本体を評価し終えると、 ポイントとマークはもとの位置に戻される。
しかし、新たに挿入したテキストの最後にマークを、先頭にポイントを設定 しておくと便利である。 変数newmark
は挿入したテキストの最後を記録している。 let
式の最後の行の式(push-mark newmark)
で、 このようにマークを設定する (そのまえのマークの位置も参照できる。 つまりマークリングに記録されているので、C-u C-SPCで戻れる)。 一方、ポイントは挿入したテキストの先頭にあり、 挿入する関数を呼ぶまえの位置のままである。
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
の1つの使い方を示した。 これらのすべての関数は、何度も何度も使う構成部品である。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
beginning-of-buffer
の完全な定義 (2004/08/05)
beginning-of-buffer
の完全な定義"へのコメント(無し)
関数beginning-of-buffer
の基本的な構造はすでに説明した (See 節 4.2 beginning-of-buffer
の簡略した定義 (2004/08/04))。
まえに説明したように、引数なしでbeginning-of-buffer
を起動すると、 カーソルをバッファの先頭に移動し、マークを移動前の位置に設定する。 ところが、1〜10までの数nを指定して起動すると、 関数はその数をバッファ長を単位としたn/10と解釈し、 Emacsはバッファの先頭からn/10の位置にカーソルを移動する。 したがって、この関数をM-<で呼べばバッファの先頭にカーソルを移動するし、 C-u 7M-<で呼べばバッファの70%のところにカーソルを移動する。 引数に10より大きな数を使うと、バッファの最後にカーソルを移動する。
関数beginning-of-buffer
は、引数を指定しても、しなくても呼べる。 つまり、引数は省略できる。
5.3.1 オプションの引数 (2004/08/05) 5.3.2 引数を指定した beginning-of-buffer
(2004/08/05)Example with optional argument. 5.3.3 beginning-of-buffer
の完全なコード (2004/08/05)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
特に指定しない限り、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) (引数があれば 移動先の位置を計算する さもなければ、 (point-min)))) |
この関数は、simplified-beginning-of-buffer
に似ているが、 interactive
式には引数として"P"
があり、 関数goto-char
に続けて、引数が指定された場合に 移動先を計算するif
式がある点が異なる。
interactive
式の"P"
は、前置引数がある場合にはそれを 関数に渡すことをEmacsに指示する。 前置引数は、METAキーに続けて数をタイプするか、 C-uをタイプしてから数をタイプする (数をタイプしないと、C-uのデフォルトは4である)。
if
式の判定条件は単純で、単に引数arg
である。 arg
にnil
以外の値があるのは、 引数を指定してbeginning-of-buffer
が呼ばれた場合であり、 if
式の真の場合の動作を評価する。 一方、引数なしでbeginning-of-buffer
を呼ぶと、 arg
の値はnil
となりif
式の偽の場合の動作が評価される。 偽の場合の動作は単純であり、point-min
である。 このように評価される場合は、goto-char
式全体は (goto-char (point-min))
となり、 関数beginning-of-buffer
の簡略な場合と同じである。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
beginning-of-buffer
(2004/08/05)
beginning-of-buffer
"へのコメント(無し)
引数を指定してbeginning-of-buffer
を呼ぶと、 goto-char
に渡す値を計算する式が評価される。 この式は、一見、複雑なように見える。 これには、内側にif
式や多くの算術演算がある。 つぎのとおりである。
(if (> (buffer-size) 10000) ;; バッファサイズが大きな場合の桁溢れを防ぐ! (* (prefix-numeric-value arg) (/ (buffer-size) 10)) (/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10)) |
Disentangle beginning-of-buffer
大きなバッファでの動作 小さなバッファでの動作
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
beginning-of-buffer
beginning-of-buffer
"へのコメント(無し)
複雑に見える他の式やbeginning-of-buffer
内の条件式などと同様に、この式も雛 型に当てはめてみると分かりやすくなる。 ここではif
式の雛型を使う。 この式の骨格はつぎのようになる。
(if (バッファが大きい バッファサイズを10で割ってから、引数を掛ける さもなければ、別の計算方法 |
内側のif
式の判定条件では、バッファサイズを調べる。 古いEmacs Lispの第18版では、(大きな数は必要ないので)8百万を超える数は扱えず、 バッファが大きな場合にEmacsがこの制限を超えるような数を 計算する可能性があるので、このような検査をしていた。 注釈中の「桁溢れ(overflow)」は、数が大きすぎることを意味する。Emacs 21 では大 きな数を使えるが,このコードは変更されていない.以前よりもずっと大きなバッファを 見るようになってきたためだ.
バッファが大きい場合とそうでない場合の2つの場合がある。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
beginning-of-buffer
では、内側のif
式で バッファサイズが10000文字より大きいかどうかを検査する。 これには関数>
と関数buffer-size
を使う。
つぎのとおりである。
(if (> (buffer-size) 10000) |
バッファが大きな場合、if
式の真の場合の動作が評価される。 (読みやすいように整形すると)その行はつぎのようになる。
(* (prefix-numeric-value arg) (/ (buffer-size) 10)) |
この式は乗算であり、関数*
には2つの引数を渡す。
第1引数は(prefix-numeric-value arg)
である。 interactive
の引数に"P"
を使うと、 関数に引数として渡される値は数ではなく、「生の前置引数(raw prefix argument)」 である(数のリスト)。 数値演算を施すには、変換する必要があり、 それにはprefix-numeric-value
を使えばよい。
第2引数は(/ (buffer-size) 10)
である。 この式は、バッファの大きさの数を10で割る。 これにより、バッファサイズの1/10に相当する文字数が得られる (Lispでは、*
を乗算に使うように、/
を除算に使う)。
乗算の式全体では、この値に引数の値を掛ける。 乗算はつぎのようになる。
(* 前置引数の値 バッファの文字数の1/10) |
たとえば、前置引数が`7'ならば、1/10に相当する値に7を掛け、 バッファの70%の位置になる。
つまり、バッファが大きな場合には、以上の結果から、 goto-char
式はつぎのようになる。
(goto-char (* (prefix-numeric-value arg) (/ (buffer-size) 10))) |
これにより、望みの位置にカーソルが移動する。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
バッファが10000文字未満の場合には、少々異なる計算を行う。 最初の計算方法で十分であり、このようなことは不要と考える読者もいよう。 しかし、小さなバッファでは、最初の計算方法では、目的の行に正しく カーソルを移動できず、2番目の計算方法のほうがよい。
コードはつぎのとおりである。
(/ (+ 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で割り、バッファの目的の位置より1だけ大きな数を得る。
この計算結果をgoto-char
に渡してカーソルを移動する。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
beginning-of-buffer
の完全なコード (2004/08/05)
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) ;; Avoid overflow for large buffer sizes! (* (prefix-numeric-value arg) (/ (buffer-size) 10)) (/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10)) (point-min))) (if arg (forward-line 1))) |
2つの小さな点を除いて、この関数はまえに述べたような動作をする。 最初の点は、説明文字列に関する部分であり、 第2の点は関数の最後の行である。
説明文字列では、つぎの式を参照している。
\(goto-char (point-min)) |
この式の最初の括弧のまえには`\'がある。 この`\'は、シンボリック式として評価するのではなく 説明文として式を表示するようにLispインタープリタに指示する。
コマンドbeginning-of-buffer
の最後の行は、 引数を指定してコマンドを起動した場合に、ポイントを次行の先頭に移動する。
(if arg (forward-line 1))) |
これにより、バッファの適切なn/10の位置の直後の行の先頭にカーソルを置く。 これは、すくなくともバッファの指定されたn/10の位置にカーソルを位置決めして 見栄えをよくするためのもので、必要ないことかもしれないが、 こうしないと不満のもとになる。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本章で説明したことがらをまとめておく。
or
nil
以外の値を返した最初の値を返す。 nil
以外の値を返すものがなければ、nil
を返す。 つまり、引数の最初の真の値を返す。 1つでも真のものがあれば、真の値を返す。
and
nil
ならばnil
を返す。 nil
でないものがなければ、最後の引数の値を返す。 つまり、すべての引数が真ならば真の値を返す。
&optional
prefix-numeric-value
(interactive "P")
で得た「生の前置引数」を数値に変換する。
forward-line
forward-line
は可能なだけ進めて、指定量に満たない行数を返す。
erase-buffer
bufferp
t
を、さもなければnil
を返す。[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
optional
引数の演習問題optional
引数の演習問題"へのコメント(無し)
省略できる引数に指定した数がfill-column
の値に比べて 大きいか小さいかをメッセージに表示する対話的関数を書いてみよ。 ただし、関数に引数を渡されなかった場合のデフォルトは56とする。
[ << ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |