18

Emacs 24 には、字句スコープの変数が含まれるようになりました。もちろん、動的スコープの変数もまだあります。両方があるので、変数がいつどのようなスコープを持つかについて、私はかなり混乱しています。レキシカルバインディングがいつ有効になるかを制御する変数があり、動的スコープの変数を宣言するlexical-bindingことについて何か読んだと思いますが、一般的にはかなり迷っています。defvarEmacs 24 の新しいスコープ規則のどこかに適切な説明がありますか? 別の言い方をすれば、Emacs 24 用に書かれた Emacs Lisp コードの変数を見たとき、その変数が使用しているスコープをどのように確認すればよいでしょうか?

4

2 に答える 2

21

マニュアルは決定的なソースです。ここから始める:

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

于 2011-10-05T04:07:57.593 に答える
4

いくつかのコードが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.elmah-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) に対する答えは、マクロを定義したバッファーではなく、マクロを呼び出したコードが存在するバッファーです。

于 2013-08-16T13:23:42.243 に答える