オブジェクトが名前付きか匿名かをチェックする安全な方法を特定しようとしています。どうやらそれは、オブジェクトのいくつかのタイプで動作しますelisp:オブジェクトが関数であることをテストします。
(defun function-check (x)
(and (boundp 'x)
(if (symbolp x) (fboundp x)
(functionp x))))
:functionp
またはfboundp
として
が、私はエラーを与えて予想したように、私がしようとしています動作しません。とにかく
(setq lfun (lambda() "hello"))
(function-check lfun) ; -> t
(setq nfun 'buffer-name)
(function-check nfun) ; -> t
(setq slfun '(lambda() "hello"))
(function-check slfun) ; -> t
(function-check 'not-bound) ; -> safe nil
、私のコードを見て、それそのような単純な作業のためにあまりにも冗長で畳み込まれているようです。
それを改善することは可能ですか?
更新:尋ねたよう
、私は私が何を意味するかを明確「functionp
、fboundp
は、今、私が期待どおりに動作します」。
有効なフックを検出するとします。これは動作しません:
(setq var 'buffer-name)
(functionp 'var) ;nil
(fboundp 'var) ;nil
我々が使用する必要があります。私たちはvar
がそうでなければ、我々は、エラーを取得し、無効でないことを確認する必要があり、
(functionp var) ;t
(fboundp var) ;t
を、これは動作しますが:
(functionp void-var) ;Lisp-error
(fboundp void-var) ;Lisp-error
状況に応じて、これは追加の制御コードの追加、コードのコンパイルなどを意味します。
有効なフックは呼び出し可能なオブジェクトです:マクロ、関数、lambdasは有効なフックです。とにかくfunctionp
は、マクロでは動作しません:
(defmacro mac() "hello")
(functionp 'mac) ;nil
fbound
は、ラムダ式では動作しませんが:変数に式を割り当てる場合
(functionp '(lambda() t)) ;t
(functionp (lambda() t)) ;t
(fboundp '(lambda() t)) ;Lisp error
(fboundp (lambda() t)) ;Lisp error
また、これは起こります:
(setq var '(lambda() t))
(functionp var) ;t
(fboundp var) ;Lisp error
ましたvar
がシンボルの場合はテストが必要な場合があります。
私が理解しているように、呼び出し可能なオブジェクトをテストするストレートな方法はないので、私の試みです。
私はelispの手を話すことができませんが、これは恐ろしくバギーに見えます:あなたはおそらく '(または(functionp x)(と(symbolp x)(fboundp x)))' 'を望んでいます: xを引用する。それでも、(funcall(lambda ....)...) 'がelispで動作するのか、' functionp'がそのようなリストについて何を言うのかを忘れてしまいます。 – tfb
'functionp'の何が問題なのですか?これは、オブジェクトが関数かどうかをテストする関数です。あなたは何の誤りを言っていますか?あなたが 'functionp'と同じ定義を使用していないなら、あなたはどのように"オブジェクトは関数 "を定義しますか? – Gilles
@Gilles私は 'functionp'はあなたが言うようにおそらく答えだと思います:それはelispで'(functionp 'car) 'が真であるように見えます:Common Lispではfalseです。 – tfb