Next: ダイナミックバインディングの正しい使用, Up: 変数のバインディングのスコーピングルール [Contents][Index]
デフォルトでは、Emacsにより作成されるローカル変数のバインディングはダイナミックバインディングです。ある変数がダイナミックにバインドされていると、Lispプログラムの実行における任意のポイントでのカレントバインディングは、単にそのシンボルにたいしてもっとも最近作成されたダイナミックなローカルバインディング、またはそのようなローカルバインディングが存在しなければグローバルバインディングになります。
以下の例のように、ダイナミックバインディングはダイナミックスコープとダイナミックエクステントをもちます:
(defvar x -99) ;x
は初期値として-99を受け取る (defun getx () x) ; この関数内ではx
は自由に使用される (let ((x 1)) ;x
はダイナミックにバインドされている (getx)) ⇒ 1 ;;let
フォームが終了した後に ;;x
は前の値-99にリバートされる (getx) ⇒ -99
関数getx
はx
を参照します。defun
構文自体の中にx
にたいするバインディングが存在しないという意味において、これはフリーな参照です。x
が(ダイナミックに)バインドされているlet
フォーム内からgetx
を呼び出すと、ローカル値(つまり1)が取得されます。しかしその後let
フォームの外側からgetx
を呼び出すと、グローバル値(つまり-99)が取得されます。
以下はsetq
を使用してダイナミックに変数をバインドする例です:
(defvar x -99) ;x
は初期値として-99を受け取る (defun addx () (setq x (1+ x))) ;x
に1加算して新しい値をリターンする (let ((x 1)) (addx) (addx)) ⇒ 3 ;addx
を2回呼び出すとx
に2回加算される ;;let
フォームが終了した後に ;;x
は前の値-99にリバートされる (addx) ⇒ -98
Emacs Lispでのダイナミックバインディングは、シンプルな方法で実装されています。シンボルはそれぞれ、シンボルのカレントのダイナミック値(または値の不在)を指定する値セルをもちます。シンボルの構成要素を参照してください。あるシンボルがダイナミックなローカル値を与えられたとき、Emacsは値セルの内容(または値の不在)をスタックに記録して、新しいローカル値を値セルに格納します。バインディング構文が実行を終えたとき、Emacsはスタックから古い値をpopして値セルにそれを配置します。
ダイナミックバインディングを使用したコードのネイティブコンパイル時には、ネイティブコンパイラーはLisp固有の最適化を何も行わないことに注意してください。