Next: , Previous: , Up: バイトコンパイル   [Contents][Index]


17.6 クロージャ関数オブジェクト

バイトコンパイルされた関数はクロージャという特別なデータタイプを使用します。クロージャはバイトコンパイル済み関数だけではなく、インタープリトされるLisp関数でも使用されます。そのようなオブジェクトが呼び出す関数として出現した際には、Emacsはバイトコンパイル済みコードまたは非コンパイル済みコードのいずれかを実行するために、常に適切なインタープリターを使用します。

内部的にはクロージャはベクターとよく似ています。バイトコード関数オブジェクトの要素にはarefを通じてアクセスできます。バイトコード関数オブジェクトのプリント表現(printed representation)はベクターと似ていて、開き‘[’の前に‘#’が追加されます。バイト関数オブジェクトは少なくとも4つの要素をもたねばならず、その要素数に上限はありません。しかし通常使用されるのは最初の6要素です。これらは:

argdesc

引数の記述子(descriptor)。これは引数リストの機能で説明されるような引数のリスト、または要求される引数の個数をエンコードする整数のいずれかである。後者の場合、その記述子の値は0ビットから6ビットで引数の最小個数、8ビットから14ビットで引数の最大個数を指定する。引数リストが&restを使用するなら7ビットがセットされて、それい以外ならクリアーされる。

クロージャがバイトコンパイル済み関数でargdescがリストなら、そのバイトコード実行前に引数はダイナミックにバインドされる。argdescが整数なら、引数リストはそのバイトコード実行前にバイトコーピンタープリンターのスタックにpushされる。

code

インタープリターに解釈される関数にたいして、この要素は関数のbodyを形成するLispフォームからなるリスト。バイトコンパイル済み関数にたいしてはバイトコード命令を含んだ文字列。

constants

バイトコンパイル済み関数にたいしては、これはコードによって参照されるLispオブジェクトのベクターを保持する。これには関数の名前や変数の名前として用いられるシンボルが含まれる。インタープリターに解釈される関数にたいしては、その関数がダイナミックなスコープをもつ古いEmacs Lisp方言を使用していればnil、そうでなければその関数のレキシカル環境を保持する。

stacksize

この関数が要するスタックの最大サイズ。インタープリターに解釈される関数の場合には、この要素は未使用のまま。

docstring

(もしあれば)ドキュメント文字列。それ以外はnil。ドキュメント文字列がファイルに格納されている場合、値は数字かリストかもしれない。本当のドキュメント文字列の取得には、関数documentationを使用する(ドキュメント文字列へのアクセスを参照)。

interactive

(もしあれば)インタラクティブ仕様。文字列かLisp式。インタラクティブでない関数ではnil

以下はバイトコード関数オブジェクトのプリント表現の例です。これはコマンドbackward-sexpの定義です。

#[256
  "\211\204^G^@\300\262^A\301^A[!\207"
  [1 forward-sexp]
  3
  1793299
  "^p"]

バイトコードオブジェクトを作成するプリミティブな方法はmake-byte-codeです:

Function: make-byte-code &rest elements

この関数はelementsを要素とするバイトコードオブジェクトを表すクロージャを構築してリターンする。

あなた自身で要素を収集してバイトコード関数を構築しないでください。それらが矛盾する場合、その関数の呼び出しによりEmacsがクラッシュするかもしれません。これらのオブジェクトの作成は常にバイトコンパイラーにまかせてください。(願わくば)バイトコンパイラーは要素を矛盾なく構築します。

インタープリターに解釈される関数を作成するプリミティブな方法はmake-interpreted-closureです:

Function: make-interpreted-closure args body env &optional docstring iform

この関数は引数がargs、bodyがbody (非nilなLispフォームのリストでなければならない)から形成されるような、インタープリターに解釈される関数を表すクロージャを構築してリターンする。enveval (evalについてを参照)で使用されるのと同じ形成によるレキシカル環境。ドキュメントdocstringが非nilなら文字列でなければならず、インタラクティブなフォームiformが非nilなら、(interactive arg-descriptor)のようなフォームであること(interactiveの使用を参照)。

This page has generated for branch:emacs-30, commit:ab5505a8acf795c0a0a2745dd6fb666954c6a4bb to check Japanese translation.