4

clojureの関数への引数のメタデータを一般的に取得する方法はありますか? この質問に投稿された回答は、実際には一般的に機能しません。

user> (defn foo "informative dox!" [] 1)
#'user/foo
user> (defmacro get-docs [func] `(:doc (meta (var ~func))))
#'user/get-docs
user> (get-docs foo)
"informative dox!"
user> (get-docs (identity foo))
; Evaluation aborted.
user> (defn process-docs [f] (let [docs (get-docs f)] (reverse docs)))
; Evaluation aborted.

varリストで呼び出すことができないため、最後から 2 番目の行は機能しません(identity foo)。また、最後の行は、コンパイラが解決できないと不平を言うため、コンパイルさえしませんf

私が見つけたこの問題の解決策のほとんどは、関数の定義内のシンボルまたはそのようなものにアクセスできるという考えに依存しているため、またはのようなことができ(resolve 'f)ます(var f)。しかし、その情報がわからない関数への引数で使用できるものが必要です。

基本的に、以下の疑問符の代わりに式を入れて、のメタデータを取得したいと思います#'map

(let [x map] (??? x))
4

1 に答える 1

5

可能ですが、一口です:

(let [x map]
   (:doc (meta (second (first (filter #(and (var? (second %))
                                            (= x (var-get (second %))))
                                      (ns-map *ns*)))))))

望ましい結果が得られます。

"Returns a lazy sequence consisting of the result of applying f to the
 set of first items of each coll, followed by applying f to the set
 of second items in each coll, until any one of the colls is\n  exhausted.  Any remaining items in other colls are ignored. Function
 f should accept number-of-colls arguments."

内部では 名前空間は基本的に変数への名前のマップであり、変数には関数が含まれています。これらの変数の内容を検索して、探している関数に一致するものを探し、関連する変数を見て、その変数からメタデータを取得できます。

于 2012-09-14T23:35:43.810 に答える