Emacs 24 には、字句スコープの変数が含まれるようになりました。もちろん、動的スコープの変数もまだあります。両方があるので、変数がいつどのようなスコープを持つかについて、私はかなり混乱しています。レキシカルバインディングがいつ有効になるかを制御する変数があり、動的スコープの変数を宣言するlexical-binding
ことについて何か読んだと思いますが、一般的にはかなり迷っています。defvar
Emacs 24 の新しいスコープ規則のどこかに適切な説明がありますか? 別の言い方をすれば、Emacs 24 用に書かれた Emacs Lisp コードの変数を見たとき、その変数が使用しているスコープをどのように確認すればよいでしょうか?
2 に答える
マニュアルは決定的なソースです。ここから始める:
C-hig (elisp) Variable Scoping
RET
この回答で最初にマニュアルを引用しましたが、その情報 (Emacs 24.0.90.1 までさかのぼる) は少し古くなっています。使用しているバージョンの情報が正しくなるように、Emacs 内からマニュアルを読むことをお勧めします。
特に Web ページで読みたい場合、現在のバージョンは次のとおりです:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html
いくつかのコードがEmacsで段階的に評価されているとしましょう(あなたが行ったばかりC-x C-e
のため、Emacs Lispファイルがロードされているため、またはフックからの関数が実行されているためなど)、Emacsは内部で評価しようとしていmy-abc
ます.そのコード。おそらくmy-abc
、そのコードのローカル変数であるか、宣言されていないか、何らかのグローバル値を持っている可能性があります。とにかく、現在のステップは の評価ですmy-abc
。その時点で、Emacs はmy-abc
レキシカル スコープを使用して評価するかどうかを決定するために 2 つのことだけをチェックします。
Emacs が最初にチェックするのはmy-abc
、「特殊変数ですか?」です。(defvar my-abc ...)
or (defcustom my-abc ..)
or etc が過去の任意の時点で実行された場合、その質問に対する答えは「はい」です。他のEmacs Lisp ファイルのロード中に実行された可能性があります。または、スクラッチ バッファーに(defcustom my-abc ..)
含まれるコードを評価したか、または評価しなかった可能性があります。(defvar my-abc ...)
何らかの理由で答えが「はい」の場合、この時点で Emacs はmy-abc
動的スコープを使用して評価します。
my-abc
答えが「いいえ」の場合、Emacs は、(A) 「私 (Emacs) がステップスルーしているこのコード (の使用を含む) はどこにあるのか?」という 2 番目のことをチェックします。これは (B) 「現在のバッファは何ですか?」 ではありません。バッファ上で Cx Ce を押したfoo.el
場合、たとえば 、および Cx ce を押した式に で定義されている名前の関数へのmah-hello
呼び出しが含まれていてmah-stuff.el
、mah-hello
関数本体にmy-hello
で定義されている名前の関数への呼び出しが含まれていた場合my-stuff.el
、および関数本体にmy-hello
という名前の変数が使用されているmy-abc
場合、Emacs が最終的に実行my-hello
を開始し、そこで評価しようとするとmy-abc
、Emacs が質問 A を尋ねた時点で、それmy-stuff.el
自体に答えます。バッファではありませんfoo.el
開始式が含まれています。
次に、Emacs は「my-stuff.el
レキシカル スコープのバッファーですか、つまり、lexical-binding
そのバッファーで true ですか?」と尋ねます。はいの場合、Emacs はmy-abc
字句スコープを使用して評価し、そうでない場合は動的スコープを使用します。
いくつかの更新: また、コードがデータとして引用されてからeval
関数に渡されると、(A) に対する答えはバッファになりません。それでも、eval
コードを配置するための架空のバッファーを作成し、そのバッファーの のバッファーローカル値をlexical-binding
に渡される 2 番目の引数に設定するかのようeval
です。(A) に対する答えは、'eval' 呼び出しを含むバッファではありません。これは架空のバッファーです。
Lisp マクロの場合、マクロ展開されたコードが実行されると、マクロを呼び出したコードを含むバッファに展開されたコードが書き込まれるかのようになります。したがって、この場合の (A) に対する答えは、マクロを定義したバッファーではなく、マクロを呼び出したコードが存在するバッファーです。