2012-09-19 3 views
6

は、現在の呼び出し時にスコープシンボル/値のマップを返しますリターンすべてのシンボルの機能を持たせることができる場合、私は思っていたClojureで現在有効なシンボルをすべて返す式ですか?

(in-ns silly.fun) 

(def a 1) 

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

、以下を想定します。だから、上記がコンパイルされ、私たちは 'silly.fun名前空間にあったと仮定して、次のようなものを実行できます。

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

デバッグの目的でreturn-all-symbolsを使用したいと思います。すべてリターンオールシンボルが可能ですか?もしそうなら、その実装は何ですか?

答えて

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#] [[email protected]] 
       :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]} 
+1

本当にあなたが何をしたかを解析するためにいくつかの時間がかかるだろうが、私はそれを試してみましたし、動作しているようです。私を感心させてくれます。 –

2

ネームスペースには、現在スコープ設定されているすべてのマップを含むマップが含まれています。

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

あなたがこれ以上を必要とするならば、あなたはJavaデバッグ インタフェースを使用して、実際のデバッガが必要な場合があります。まだ、デバッグのために有用であるかもしれないけれどもそれは(let [x 4] (return-all-symbols))のような式からlexicalyスコープのシンボルを見逃すことでしょう。チェックアウトthe clojure debugging toolkit

2

(ns-interns)かもしれませんあなたは何をしたいのですが、(ns-map)(lazy-seq)で囲んで使うと、大きな名前空間に適しています。

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...}