2016-03-30 6 views
2

で無効です。免責事項:私は今日elispでハックし始めました。Elisp:変数としてのシンボルの値は、let *および(lambda)

私は本当に私は、次のエラーを取得しています何を疑問に思って:次のコードで

Symbol's value as variable is void: response 

(let* ((response (cons 'dict nil))) 
    (nrepl-request:eval 
    code 
    (lambda (resp) 
     (print resp (get-buffer "*sub-process*")) 
     (nrepl--merge response resp)) 
    (cider-current-connection) 
    (cider-current-session))) 

私の理解では、呼び出されたときにresponselet*条項の範囲にあることですラムダ関数から...しかし明らかにそれはそうではありません。

This also seem to be working in this code

だから私は少し私はこのエラーを取得していますし、私はそれについて何をすべき理由について失われています。

+0

動的バインディングでは、あなたのラムダが*定義されているときに 'response'の値がバインドされますが、そのスコープ内で関数が呼び出されていないことは明らかです。もちろん他の場所に縛られていない限り)。 – phils

答えて

6

グローバル変数lexical-bindingをソースファイル内のファイルローカル変数として設定することによって、レキシカルバインディングを指定する必要があります。

;;; -*- lexical-binding: t -*- 

どちらかはそれを行うか、代わりにlet*lexical-let*を使用:ファイルの最初の行として次のような行を入れてください。また

、あなたは関数が定義された時にのみ、その値を必要とする場合は、あなたがこれを使用することができ、つまり、匿名関数が呼び出される変数として変数responseを必要としない場合:

をレキシカル変数で
(let* ((response (cons 'dict nil))) 
    (nrepl-request:eval 
    code 
    `(lambda (resp) 
     (print resp (get-buffer "*sub-process*")) 
     (nrepl--merge ',response resp)) ; <===== Substitute value for variable 
    (cider-current-connection) 
    (cider-current-session))) 

ファイルをバイトコンパイルするとき、ラムダフォームはコンパイルされます。変数がなければ(すなわち、その値だけで)、ラムダフォームはコンパイルされません。これは単なるリスト(車lambdaなど)です。

+0

素晴らしい、これはまさに私が逃したものです。 – Neoasimov

関連する問題