6

次のように仮定します。

(in-ns silly.fun)

(def a 1)

(defn fx [b]
  ((fn [c] (return-all-symbols)) (first b)))

呼び出し時に現在スコープされているシンボル/値のマップを返すreturn-all-symbols関数を使用できるかどうか疑問に思いました。したがって、上記がコンパイルされ、'silly.fun名前空間にいると仮定すると、次のようなものを実行できます。

(fx [:hello]) => {"a" 1, "b" [:hello], "c" :hello}

デバッグの目的でreturn-all-symbolsを使用したいと思います。return-all-symbolsは可能ですか?もしそうなら、その実装は何ですか?

4

3 に答える 3

8

それは可能ですが、あなたがそれを定義したように、あなたはかなり悲しいでしょう:clojure.coreのすべての関数を参照する何百ものエントリを持つマップは必要ありません!また、現在の名前空間だけを調べても、fx値が関数であるシンボルであるを含めるのを忘れていました。さらに、マクロによって導入された、不要な字句記号がよくあります。たとえば、(let [[x y] foo])foo、x、y、およびのような4つのシンボルが表示されますvec__auto__4863

とにかく、あなたはおそらくそれらの問題について妥協して生きなければならないでしょう、さもなければ(そして本当に私はこれがより良いと思います)あなたが実際にマップしたいシンボルを指定します。ただし、(a)字句または(b)現在の名前空間で定義され、(c)関数にマッピングされていない記号の値を自動的に取得するには、次を使用できます。

(defmacro return-all-symbols []
  (let [globals (remove (comp :macro meta val) (ns-publics *ns*))
        syms (mapcat keys [globals, &env])
        entries (for [sym syms]
                  [`(quote ~sym) sym])]
    `(into {}
           (for [[sym# value#] [~@entries]
                 :when (not (fn? value#))]
             [sym# value#]))))


(def a 1)

(defn fx [b]
  ((fn [c] (return-all-symbols)) (first b)))

(fx [:hello])
;=> {a 1, c :hello, b [:hello]}
于 2012-09-19T22:56:34.223 に答える
2

名前空間には、現在スコープが設定されているすべての変数を含むマップが含まれています。これにより、必要なものの一部が得られます。(let [x 4] (return-all-symbols))デバッグにはまだ役立つかもしれませんが、式から字句スコープの記号が欠落します。

core> (take 2 (ns-map *ns*))
([sorted-map #'clojure.core/sorted-map] [read-line #'clojure.core/read-line])  

これ以上が必要な場合は、Javaデバッグインターフェイスを使用する実際のデバッガーが必要になる場合があります。clojureデバッグツールキットをチェックしてください

于 2012-09-19T22:06:32.553 に答える
2

(ns-interns)が必要な場合もありますが、 (lazy-seq)でラップされた(ns-map)を使用すると、大きな名前空間に適しています。

1   (ns-map 'clojure.core)
2   {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, ClassVisitor clojure.asm.ClassVisitor, asm-type #'clojure.core/asm-type, val #'clojure.core/val, ...chop...}


于 2012-09-20T00:18:20.330 に答える