10.5 evalについて

フォームはほとんどの場合、実行されるプログラム内に出現することにより自動的に評価されます。ごく稀に実行時 — たとえば編集されているテキストやプロパティリストから取得したフォームを読み取った後 — に計算されるようにフォームを評価するコードを記述する必要があるかもしれません。このようなときはeval関数を使用します。evalが不必要だったり、かわりに他の何かを使用すべきときがよくあります。たとえば変数から値を取得するにはevalも機能しますが、symbol-valueのほうが適しています。evalで評価するためにプロパティリストに式を格納するかわりに、funcallに渡すように関数を格納した方がよいでしょう。

このセクションで説明する関数と変数はフォームの評価、評価処理の制限の指定、最後にリターンされた値の記録を行なうものです。ファイルのロードでも評価が行なわれます(ロードを参照)。

データ構造に式を格納して評価するより、データ構造に関数を格納してfuncallapplyで呼び出すほうが、より明解で柔軟です。関数を使用することにより、引数に情報を渡す能力が提供されます。

Function: eval form &optional lexical

これは式を評価する基本的な関数である。この関数はカレント環境内でformを評価して、その結果をリターンする。formオブジェクトの型はそれが評価される方法を決定します。フォームの種類を参照のこと。

引数lexicalは、ローカル変数にたいするスコープ規則(変数のバインディングのスコーピングルールを参照)を指定する。tならレキシカルスコープを使用してformを評価することを意味する(これが推奨値)。省略かnilなら、ダイナミック変数のみの古いスコープルールを使用することを意味する。これが省略またはnilならデフォルトのダイナミックスコープ規則を使用してformを評価することを意味する。tならレキシカルスコープ規則が使用されることを意味する。lexicalの値にはレキシカルバインディングでの特定のレキシカル環境(lexical environment)を指定する空ではないalistも指定できる。しかしこの機能はEmacs Lispデバッガーのような、特別な用途にたいしてのみ有用。レキシカルバインディングを参照のこと。

lexicalの値はレキシカルバインド向けに特定のレキシカル環境(lexical environment)を指定する非空のリストでもよい。ただしこれはEmacs Lispデバッガのように特化した用途にたいしてのみ役に立つだろう。このリストのメンバーはそれぞれレキシカルなシンボル/値ペアーを表すコンスセル、あるいはバインドされるとダイナミックスコープを用いる(特別な)変数を表すシンボルである。

evalは関数なのでeval呼び出しに現れる引数式は2回 — evalが呼び出される前の準備で一度、eval関数自身によりもう一度 — 評価される。以下に例を示す:

(setq foo 'bar)
     ⇒ bar
(setq bar 'baz)
     ⇒ baz
;; evalが引数fooを受け取る
(eval 'foo)
     ⇒ bar
;; evalが、fooの値である、引数barを受け取る
(eval foo)
     ⇒ baz

evalで現在アクティブな呼び出しの数はmax-lisp-eval-depthに制限される(以下参照)。

Command: eval-region start end &optional stream read-function

この関数はカレントバッファー内の、位置startendで定義されるリージョン内のフォームを評価する。この関数はリージョンからフォームを読み取ってevalを呼び出す。これはリージョンの最後に達するか、処理されないエラーがシグナルされるまで行なわれる。

デフォルトではeval-regionは出力を何も生成しない。しかしstreamが非nilなら出力関数(出力関数を参照)で生成された任意の出力、同様にリージョン内の式を評価した結果の値が、streamを使用してプリントされる。出力ストリームを参照のこと。

read-functionが非nilなら、readのかわりに1つずつ式を読み取るために使用する関数を指定すること。これは入力を読み取るストリームを指定する、1つの引数で呼び出される関数である。この関数を指定するために変数load-read-function(How Programs Do Loadingを参照)も使用できるが、引数read-functionを使用するほうが堅実である。

eval-regionはポイントを移動しない。常にnilをリターンする。

Command: eval-buffer &optional buffer-or-name stream filename unibyte print

この関数はeval-regionと似ているが、引数は異なるオプション機能を提供する。eval-bufferはバッファーbuffer-or-nameのアクセス可能な部分(Narrowing in The GNU Emacs Manualを参照)の全体を処理する。buffer-or-nameにはバッファー名(文字列)を指定でき、nil(または省略)のときはカレントバッファーを意味する。streamが非nil、またはprintnilなら、eval-regionのようにstreamが使用される。この場合には式の評価結果の値は依然として破棄されるが、出力関数による出力はエコーエリアにプリントされる。filenameload-history (アンロードを参照)に使用されるファイル名であり、デフォルトはbuffer-file-name (バッファーのファイル名を参照)。unibyteが非nilならread可能な限りは文字列をユニコードに変換する。

User Option: max-lisp-eval-depth

この変数はエラー(エラーメッセージは"Lisp nesting exceeds max-lisp-eval-depth")がシグナルされる前にevalapplyfuncallの呼び出しで許容される最大の深さを定義する。

超過した際にエラーを起こすこの制限は、誤って定義された関数による無限再帰をEmacs Lispが回避するための手段として用いられる。max-lisp-eval-depthの値を過大に増加させると、そのようなコードはかわりにスタックオーバーフローを起こすだろう。オーバーフローを処理できるシステムがいくつかある。この場合には通常のLisp評価は割り込まれて、制御はトップレベルのコマンドループ(top-level)に戻される。この状況ではEmacs Lispデバッガにエンターする手段は存在しないことに注意されたい。エラーによるデバッガへのエンターを参照のこと。

Lisp式に記述された関数の呼び出し、関数呼び出しの引数と関数bodyフォームにたいする再帰評価、Lispコード内での明示的な呼び出し等では内部的にevalapplyfuncallを使用して深さ制限を計数する。

この変数のデフォルト値は1600。この値を100未満にセットした場合には、値が与えられた値に達するとLispはそれを100にリセットする。

User Option: lisp-eval-depth-reserve

無限再帰エラーのデバッグを可能にするために、空き領域がほとんど存在しない場合にデバッガ自体を実行できる空き領域を確保するためにLispデバッガ呼び出し時にEmacsがmax-lisp-eval-depthの値を一時的に増加する。handler-bindのハンドラー実行時にも同じことが発生する。エラーを処理するコードの記述を参照のこと。

これらの例外的な状況のために変数lisp-eval-depth-reserveにはEmacsがmax-lisp-eval-depthに追加できる追加深さがバインドされている。

この変数のデフォルト値は200。

Variable: values

この変数の値は読み取り、評価、プリントを行なった標準的なEmacsコマンドにより、バッファー(ミニバッファーを含む)からリターンされる値のリストである(これには*ielm*バッファーでの評価、lisp-interaction-modeでのC-jC-x C-e、類似の評価コマンドを使用した評価は含まれないことに注意)。

この変数は時代遅れでありEmacsプロセスのメモリーフットプリントを常に増加させるため、将来のバージョンでは削除されるだろう。この理由により使用を推奨しない。

valuesの要素の順序はもっとも最近の要素が最初になる。

(setq x 1)
     ⇒ 1
(list 'A (1+ 2) auto-save-default)
     ⇒ (A 3 t)
values
     ⇒ ((A 3 t) 1 ...)

この変数は最近評価されたフォームの値を後で参照するのに有用かもしれない。values自体の値のプリントは、値がおそらく非常に長くなるので通常は悪いアイデアである。かわりに以下のように特定の要素を調べること:

;; もっとも最近評価された結果を参照する
(nth 0 values)
     ⇒ (A 3 t)
;; これは新たな要素をputするので
;;   すべての要素が1つ後に移動する
(nth 1 values)
     ⇒ (A 3 t)
;; これは次に新しい、この例の前の次に新しい要素を取得する
(nth 3 values)
     ⇒ 1

This page has generated for branch:work/emacs-30_69b16e5c63840479270d32f58daea923fe725b90, commit:5e3f74b56ff47b5bcef2526c70f53f749bbd45f6 to check Japanese translation.