Next: , Up: 変数のバインディングのスコーピングルール   [Contents][Index]


12.10.1 ダイナミックバインディング

デフォルトでは、Emacsにより作成されるローカル変数のバインディングはダイナミックバインディングです。ある変数がダイナミックにバインドされていると、Lispプログラムの実行における任意のポイントでのカレントバインディングは、単にそのシンボルにたいしてもっとも最近作成されたダイナミックなローカルバインディング、またはそのようなローカルバインディングが存在しなければグローバルバインディングになります。

以下の例のように、ダイナミックバインディングはダイナミックスコープとダイナミックエクステントをもちます:

(defvar x -99)  ; xは初期値として-99を受け取る

(defun getx ()
  x)            ; この関数内ではxは自由に使用される

(let ((x 1))    ; xはダイナミックにバインドされている
  (getx))
     ⇒ 1

;; letフォームが終了した後に
;; xは前の値-99にリバートされる

(getx)
     ⇒ -99

関数getxxを参照します。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固有の最適化を何も行わないことに注意してください。