2012-01-25 4 views
7

Po prostu spędziłem całe wieki zastanawiając się, co było nie tak z moim kodem. Działało dobrze w jednostkowych testach jednostkowych, ale nie udało się, gdy uruchomiłem go w szerszym kontekście. Oto przykład kodu, który pracował:Dlaczego kod z buforem o wartości temp. Narzeka na zmienną void, gdy bufor "rodzica" ma zmienną lokalną o tej samej nazwie, którą związałem?

(defun func (my-var) 
    (with-temp-buffer 
    (message my-var))) 

(func "z") 

Drukuje oo zgodnie z oczekiwaniami. Teraz pisałem główny tryb, który zawierał pewne lokalne zmienne buforowe. Jednym z nich był mój-var. Ten kod pokazuje mój problem:

(make-local-variable 'my-var) 
(setq my-var "y") 

(defun func (my-var) 
    (with-temp-buffer 
    (message my-var))) 

(func "z") 

Dane wyjściowe? Nie ma nikogo, tylko ten komunikat o błędzie:

eval-buffer: Symbol's value as variable is void: my-var 

W tym przykładzie jest to łatwo zauważyć, że zmienna bufor lokalny ingeruje jakoś związany z dynamicznie my-var. Nie było tak łatwo, gdy miałem kilka ekranów wartych kodu :-)

Moje pytanie brzmi: co tak naprawdę się tutaj dzieje? Oczywiste jest, że bufor tymczasowy w jakiś sposób dziedziczy zmienną z bufora "rodzica", ale dlaczego ma pustą wartość? Zrozumiałbym, gdyby w jakiś sposób uzyskał wartość "y", ale to zachowanie jest dla mnie jak błąd.

PS. Używam najnowszej wersji Aquamacs

Odpowiedz

3

Kilka rzeczy.

Po pierwsze, twój kod nie działa tak jak jest. Powinieneś spróbować tego w nowej inwokacji Emacsa. Gdy to zrobisz, zobaczysz, że trzeba zdać make-local-variable symbol, tak jak poniżej:

(make-local-variable 'my-var) 

Zanotuj `` `.

Po drugie, zdefiniowano lokalną zmienną bufora o tej samej nazwie co parametr func, więc każda odpowiedź musi je rozróżnić.

Więc oto moja oczyścić wersję swojej przykład:

(make-local-variable 'my-var) 
(setq my-var "y") 

(defun func (my-param) 
    (with-temp-buffer 
(message my-param))) 

(func "z") 

I to działa dobrze.

Co prowadzi mnie do przekonania, że ​​błąd, który widzisz, pochodzi z połączenia z make-local-variable bez cytatu przed numerem my-var.

Original odpowiedź podane poniżej, choć nie rozwiązuje problemu:


sprawdzeniu dokumentacji dla make-local-variable. Łańcuch dokumentu to:

make-local-variable to interaktywna wbudowana funkcja w kodzie źródłowym "C source ".

(make-local-variable variable)

Bądź ZMIENNA mieć osobną wartość w bieżącym buforze. Pozostałe bufory będą nadal udostępniać wspólną domyślną wartość.(Lokalna wartość zmiennej VARIABLE o wartości zaczyna się od tej samej wartości, co poprzednio posiadała VARIABLE . Jeśli VARIABLE była nieważna, pozostaje nieważna.) Return VARIABLE.

Kluczową częścią dla ciebie jest ostatnie zdanie. If the variable was void, it remains void.

Oznacza to, że jeśli nie został jeszcze zdefiniowany globalnie, nadal nie jest zdefiniowany globalnie. Innymi słowy, ma tylko wiązanie w buforach, w których zostało wyraźnie ustawione.

Jeśli chcesz go mieć wartość globalną, należy setq-default tak:

(setq-default my-var "some-default-value") 
+0

Ale ja nadal nie rozumiem, dlaczego to jest nieważne. Tworzę ją za pomocą: (make-local-variable my-var), a następnie ustawiam na nią wartość "y": (setq my-var "y"). Tak więc do czasu wywołania funkcji i makra z tempem-temp w ramach wartości nie powinno być nieważne. czego mi brakuje? – auramo

+0

"Innymi słowy, ma tylko powiązanie w buforach, w których zostało jawnie ustawione." <- Nie ustawiłem go jawnie w buforze temp utworzonym w makrze z tempem-buffer. Bufor w jakiś sposób odziedziczył zmienną, ale nie jej wartość. Poza tym nie chcę tworzyć zmiennej globalnej, jeśli mogę tego uniknąć. Mogę żyć z tą funkcją dobrze, po prostu muszę pamiętać, aby dokładnie nazwać zmienne. Chciałbym tylko wiedzieć, dlaczego tak się dzieje. – auramo

+0

Właściwie w twoim kodzie dzieje się kilka rzeczy, zaktualizuję odpowiedź. –

Powiązane problemy