2011-10-04 80 views
18

Emacs 24現在具有詞彙範圍變量。當然,它也有動態範圍的變量。既然它有兩個,我很困惑什麼時候變量會具有哪種範圍。有一個lexical-binding變量控制何時啓用詞法綁定,我想我讀了一些關於defvar的內容,現在聲明瞭一個動態範圍的變量,但總的來說我很迷茫。 Emacs 24的新的範圍規則有什麼好的解釋嗎?換句話說,當我查看爲Emacs 24編寫的Emacs Lisp代碼中的變量時,我該如何判斷該變量使用的範圍?Emacs 24中的變量作用域的新規則是什麼?

+2

如果您安裝了Emacs 24,則可以在該信息中找到該信息。打開「Emacs Lisp」節點並點擊「i」搜索索引。 –

+0

我安裝了23和24,所以它有點混亂。有「Elisp」和「Elisp(emacs-snapshot)」條目。我現在看到它。另外,我有時會忘記Emacs是具有良好文檔的項目之一,如果沒有足夠的文檔,可能不是合併主要新功能的類型。 –

回答

21

該手冊是權威性的資源。從這裏開始:

我克(elisp) Variable ScopingRET

我原本報價在這個答案的手冊,但這些信息(可以追溯到的Emacs 24.0.90.1)略有出來的日期。最好從Emacs裏面閱讀手冊,以便所使用的版本的信息是正確的。

如果你特別想讀它的網頁上,目前的版本是:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html

3

比方說,一些代碼正在評估一步步在Emacs(因爲你只是做了C-x C-e或因一個Emacs Lisp文件正在被加載,或者因爲鉤子函數正在運行等),並且Emacs將要在該代碼中評估my-abc。可能my-abc是該代碼中的局部變量,或者可能未聲明或可能具有某種全局值等。無論如何,當前步驟是評估my-abc。此時,Emacs只檢查兩件事情來決定是否使用詞法作用域來評估my-abc

Emacs檢查的第一件事是「是my-abc一個特殊變量?」。這個問題的答案是肯定的,如果(defvar my-abc ...)(defcustom my-abc ..)等在過去的任何時候運行。也許(defcustom my-abc ..)在加載其他Emacs Lisp文件時運行,或者您可能在臨時緩衝區中評估了一些包含(defvar my-abc ...)的代碼,或者可能不是。如果由於任何原因答案是肯定的,那麼Emacs在這一點上將使用動態範圍評估my-abc。如果答案是否定的,Emacs會檢查第二件事情,即(A)「我(Emacs)正在步入的代碼(包含使用my-abc)在哪裏?」。這不是(B)「現在的緩衝區是什麼?」。如果您只是在緩衝區上按下Cx Ce,例如foo.el,並且如果按下Cx ce的表達式包含對mah-stuff.el中定義的名爲mah-hello的函數的調用,並且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真?」。如果是,Emacs使用詞法作用域評估my-abc,否則使用動態作用域。

某些更新:另外,當代碼被引用爲數據然後傳遞給eval函數時,對(A)的回答將不是緩衝區。儘管如此,eval構成了放置代碼的虛擬緩衝區,並將該緩衝區的緩衝區本地值lexical-binding設置爲傳遞給eval的第二個參數。 (A)的答案是而不是包含「eval」調用的緩衝區。這是虛構的緩衝區。

對於Lisp宏,當某些宏展開代碼正在運行時,就好像展開的代碼被寫入包含調用該宏的代碼的緩衝區。因此,在這種情況下對(A)的回答是而不是定義宏的緩衝區,而是調用宏的代碼駐留的緩衝區。

+0

很好的解釋。謝謝! – killdash9

相關問題