url-retrieveからのコールバックにおける「変数としてのシンボルの値はvoid」


8

次を実行すると、エラーが発生します。

(defun caller (func)
  (url-retrieve "http://m0smith.freeshell.org/"
   (lambda (status) (funcall func))))


(caller (lambda() (message "called")))

結果:

error in process filter: Symbol's value as variable is void: func

この問題を解決する最良の方法は何ですか?基本的に、どこかからのコールバックを受け入れ、別のラムダでラップし、それをurl-retrieveへのコールバックとして使用する必要があります。

発信者をに変更した場合

(defun caller (func)
  (url-retrieve "http://m0smith.freeshell.org/"
   `(lambda (status) (funcall ,func))))

できます。ただし、funcがflycheckによって渡されており、マクロ展開によって中断されるため、これを行うことはできません。私がやっていることの完全なコンテキストを確認するには:https : //gist.github.com/m0smith/b5961fda6afd71e82983


マクロ展開とは?最後の段落は不明確です。問題の完全な説明をここに投稿してください。コンマバッククォートを使用することが解決策です(1つの解決策)。もう1つは、lexical-let変数を使用または設定することですlexical-binding。表示されていない「マクロ」の問題を明確にしてください。
2014

`および、はマクロ展開されていると想定しました。その形が何と呼ばれるにせよ。EMACS 23で作業したいのですが、字句機能はありますか?
M Smith

のない使用がない場合FUNCを超えてfuncall、その後、論理的にあなたがいないここに結合字句必要が。それを使用することに問題はありません、一部のコードが実際に変数 を使用する必要がない限り、それは必要ありませんFUNC。それが必要ない場合(これまでのところはこれまでの説明です)、その値をコンマで逆引用符を使用してその値で置き換えるだけです。
2014

字句バインディングは、Emacs 23(およびそれ以前)で使用できlexical-letます。グローバル変数は、lexical-bindingEmacsの24で利用可能です
ドリュー

回答:


5

これは、cl.elのlexical-letを使用してローカルで実現できます。

(eval-when-compile '(require 'cl))

(defun my-test-caller (func)
  (lexical-let ((ext-func func))
    (url-retrieve "http://www.google.com"
                  (lambda (status) (funcall ext-func)))))

(my-test-caller #'(lambda() (message "called")))

ヘルプが言うように明確にする:

Like `let', but lexically scoped.
The main visible difference is that lambdas inside BODY will create
lexical closures as in Common Lisp.

Emacs 24.1で追加された字句バインディングを有効にすることで、同じ効果を得ることができます。これは、設定可能なバッファローカル変数であり、バッファ内のすべてのコードで字句的クロージャを有効にします。したがって、バッファは次のようになります。

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

(defun my-lexical-test-caller (func)
  (url-retrieve "http://www.google.com"
                (lambda (status) (funcall func))))

(my-lexical-test-caller
 #'(lambda()
     (message "called from lexical-binding def")))

ありがとう。しかし、私my-test-caller: Symbol's function definition is void: lexical-letは自分のemacs を取得します:KAELで2014-10-20のGNU Emacs 24.4.1(x86_64-w64-mingw32) `
M Smith

@MSmith-ahh add(require 'cl)
stsquad

lexical-letで定義されていcl-macs.elます。だから(eval-when-compile '(require 'cl))
ドリュー

cl.elこのためだけに、実行時に要求する必要はありません。lexical-letマクロなので、コンパイル時に必要になります。
2014

2
しないでください。を使用しlexical-bindingます。とにかく、FlycheckはEmacs 23をサポートしていないので、Emacs 23と互換性を持たせる意味はありません。
lunaryorn 14

5

lexical-bindingを使用して、ライブラリで有効にしますM-x add-file-local-variable-prop-line RET lexical-binding RET t

lexical-let他の回答で示唆されているように使用しないでください。Flycheck自体はEmacs 23と互換性がないため、独自のコードでEmacs 23の互換性を維持しようとしても意味がありません。


ありがとう。それが役立つので、私は理由もなく古いemacsを動作させようとはしていません
M Smith

これに字句レットを使用することの何が問題になっていますか?
stsquad 2014

@stsquad遅くなり、冗長になります。lexical-binding引数自体はレキシカルスコープされているため、追加的な結合のための必要は、ありません。さらに、lexical-binding真のクロージャを作成しますが、非lexical-letインターンシンボルを使用して字句バインディングをエミュレートします。
lunaryorn 2014

@lunaryorn:レガシーコードの既存のバッファーで字句バインドを有効にすることにより、予期しない影響が生じるリスクはありませんか?とにかく、私は両方の解決策に言及するために私の答えを拡張しました。
stsquad 2014

@stsquadはい、未定義の変数を動的にバインドすることに依存する、不十分に記述されたレガシーコードに予期しない影響が生じる可能性がありletます。繰り返しますが、FlycheckはとにかくEmacs 24用であるため、レガシーコードについては触れていません。
lunaryorn 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.