2012-01-25 4 views
7

私は自分のコードで何が間違っていたのか考え出したばかりです。それはert単体テストでうまくいきましたが、大きな文脈でそれを実行したときには失敗しました。"親"バッファに同じ名前のローカル変数がある場合、with-temp-bufferのコードでvoid変数が返されるのはなぜですか?

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

(func "z") 

これは期待どおりにzを出力します。今私はバッファローカル変数を持ったメジャーモードを書いていました。これらのうちの1つはmy-varでした。このコードは私の問題を示しています:

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

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

(func "z") 

出力は?

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

この例では、バッファローカル変数は動的には私の-VARをバインドして何とか干渉することを確認するために簡単です:どれだけこのエラーメッセージはありません。しかし、私はコードの価値がある複数の画面を持っていたときはそれほど簡単ではなかった:-)

私の質問は本当にここで何が起こっているのですか?一時バッファが何らかの形で "親"バッファから変数を継承しているのは明らかですが、なぜそれがvoid値を持っていますか?私は何とか "y"という値を得られるかどうか分かりますが、この動作はバグのような感じです。

PS。私は最新のAquamacsを実行しています

答えて

3

いくつかのことがあります。

まず、コードがそのまま動作しません。 Emacsの新しい呼び出しでこれを試してください。あなたは一度、あなたがそうのように、make-local-variableにシンボルを渡す必要があることがわかります:

(make-local-variable 'my-var) 

注 `` `を。

第2に、パラメータと同じ名前のバッファローカル変数をfuncに定義しているため、すべての回答で2つを区別する必要があります。

だから、ここあなたの例の私のクリーンアップバージョンです:

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

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

(func "z") 

は、これはうまく動作します。

これは、表示されているエラーが、の前に引用符を付けずにmake-local-variableを呼び出したものだとわかります。それが問題を解決しませんが、以下に提供

オリジナルの答え:


make-local-variableのマニュアルをチェックしてください。 doc文字列は次のとおりです。

make-local-variableは `Cソース コード 'の対話型組み込み関数です。

(メークローカル変数VARIABLE)は

VARIABLEは、現在のバッファ内の別々の値を持っていることを確認します。他の バッファは引き続き共通のデフォルト値を共有します。( VARIABLEのバッファローカル値は、前にVARIABLE と同じ値で始まります.VARIABLEが無効であれば、それは無効のままです)。 VARIABLEを返します。

あなたのためのキーパーツが最後の文章です。 If the variable was void, it remains void.

これは、グローバルに定義されていない場合でも、グローバルに定義されていないことを意味します。言い換えれば、明示的に設定されたバッファ内にのみバインディングがあります。

それは、グローバルな価値を持っているので、同じようsetq-defaultを使用する場合:

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

しかし、それは無効であり、なぜ私はまだ理解していません。私はそれを作成します:(make-local-variable my-var)そして、それに値 "y"を設定します: (setq my-var "y")。だから私は関数を呼び出すと、値内の一時バッファーマクロが無効になるべきではありません。私は何が欠けていますか? – auramo

+0

"言い換えれば、明示的に設定されたバッファ内にのみバインディングがあります。 < - 私はtemp-bufferマクロで作成されたtemp-bufferに明示的に設定しませんでした。バッファは何とか変数を継承しましたが、値は継承しませんでした。また、私はそれを避けることができればグローバル変数を作成したくありません。私はこの機能をうまく生かすことができます、変数を慎重に覚えておいてください。私はちょうどこれがなぜ起こるか知りたいと思う。 – auramo

+0

実際には、あなたのコードの中でいくつかのことが進行中です。私は答えを更新します。 –

関連する問題