2011-10-04 21 views
18

Emacs 24 ora ha variabili con ambito lessicale. Ha anche ancora variabili con scope dinamiche, ovviamente. Ora che ha entrambi, sono abbastanza confuso su quando una variabile avrà quale tipo di scope. C'è una variabile lexical-binding che controlla quando il collegamento lessicale è abilitato, e penso di aver letto qualcosa su defvar che ora dichiara una variabile con ambito dinamico, ma in generale sono piuttosto perso. C'è una buona spiegazione da qualche parte delle nuove regole di scoping di Emacs 24? In altre parole, quando guardo una variabile nel codice Lisp di Emacs scritto per Emacs 24, come faccio a sapere quale ambito sta usando quella variabile?Quali sono le nuove regole per l'ambito della variabile in Emacs 24?

+2

Se è stato installato Emacs 24, queste informazioni sono disponibili nelle informazioni. Apri il nodo "Emacs Lisp" e premi 'i' per cercare l'indice. –

+0

Ho entrambi 23 e 24 installati, quindi è stato un po 'di confusione. C'erano entrambe le voci "Elisp" e "Elisp (emacs-snapshot)". Ora lo vedo. Inoltre, a volte dimentico che Emacs è uno dei progetti con una buona documentazione e probabilmente non il tipo per unire le nuove funzionalità principali senza una documentazione adeguata. –

risposta

21

Il manuale è la fonte definitiva. Inizia da qui:

Chig(elisp) Variable ScopingRET

avevo inizialmente citato il manuale in questa risposta, ma che le informazioni (risalente al Emacs 24.0.90.1) era un po 'fuori Data. Meglio leggere il manuale da dentro Emacs in modo che le informazioni siano corrette per la versione che stai utilizzando.

Se particolarmente desidera leggere su una pagina web, la versione corrente è:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html

3

Diciamo che un po 'di codice è in corso di valutazione, passo dopo passo in Emacs (o perché hai appena fatto C-x C-e o perché un file Emacs Lisp viene caricato o perché viene eseguita una funzione da un hook, ecc.) e che Emacs sta per valutare my-abc all'interno di quel codice. Forse my-abc è una variabile locale in quel codice o forse non è dichiarata o forse ha un valore globale, ecc. In ogni caso, il passo corrente è la valutazione di my-abc. A quel punto, Emacs controlla solo due cose per decidere se valutare my-abc usando scope lessicale o meno.

La prima cosa che Emacs controlla è "è my-abc una variabile speciale?". La risposta a questa domanda è sì se (defvar my-abc ...) o (defcustom my-abc ..) o ecc. È stato eseguito in qualsiasi punto nel passato. Forse (defcustom my-abc ..) è stato eseguito durante il caricamento di un altro file Lisp di Emacs, o forse hai valutato del codice contenente (defvar my-abc ...) sul buffer scratch, o forse no. Se la risposta è sì per qualsiasi motivo, Emacs a questo punto valuterà my-abc utilizzando l'ambito dinamico.

Se la risposta è no, allora Emacs controlla la seconda cosa, che è (A) "dove si trova questo codice (contenente uso di my-abc) che io (Emacs) sto facendo un passo fino in fondo?". Questo non è (B) "qual è il buffer corrente ora?". Se hai appena premuto Cx Ce su un buffer, ad esempio foo.el, e se l'espressione che hai premuto Cx ce conteneva una chiamata a una funzione denominata mah-hello definita in mah-stuff.el e se il corpo della funzione mah-hello conteneva una chiamata a una funzione denominata my-hello, è definito in my-stuff.el e se il corpo funzione dicontiene l'uso di una variabile denominata my-abc, quindi quando Emacs alla fine eseguirà my-hello e quindi sta per valutare my-abc lì, a quel punto quando Emacs pone la domanda A, risponde my-stuff.el a se stesso. Non il buffer foo.el che contiene l'espressione iniziale.

Quindi Emacs chiede "è my-stuff.el un buffer con scope lessicale, in altre parole, è lexical-binding true su quel buffer?".Se sì, Emacs valuta my-abc usando scope lessicale, altrimenti usa scope dinamico.

Alcuni aggiornamenti: Inoltre, quando il codice viene indicato come dati e quindi passato alla funzione eval, la risposta a (A) non sarà un buffer. Tuttavia, è come se eval componga un buffer immaginario per posizionare il codice e imposta il valore locale del buffer di lexical-binding per quel buffer sul secondo argomento passato a eval. La risposta a (A) è non il buffer contenente la chiamata 'eval'. È il buffer immaginario.

Per le macro Lisp, quando viene eseguito un codice macroexpanded, è come se il codice espanso fosse scritto nel buffer che contiene il codice che ha richiamato la macro. Pertanto la risposta a (A) in questo caso è non il buffer che ha definito la macro, ma il buffer in cui risiede il codice che ha chiamato la macro.

+0

Ottima spiegazione. Grazie! – killdash9

Problemi correlati