2013-02-08 3 views
9

私はX.clojurescriptとX.clojure名前空間を持っているとしましょう。 X.clojurescriptのすべてがClojurescriptコードであり、X.clojureのすべてがClojureコードです。残念ながら、私はClojureの中でそれらを定義し、これは大丈夫ですClojurescriptマクロから必要なClojurescriptコードを扱うにはどうすればよいですか?

(ns X.clojurescript.abc 
    (:require-macros [X.clojure.def :as clj])) 

を使用してClojurescript名前空間にそれらを持参する必要があり、Clojurescriptに直接マクロを定義することはできません。しかし、マクロ(X.clojureで定義されている)がClojurescript名前空間(X.clojurescript)で定義されたものを参照する必要がある場合はどうでしょうか?問題は、他の名前空間を解決するときに、ClojureコンパイラがClojurescript名前空間(別のディレクトリ)を見ないということです。

私はClojurescriptに存在するのと同じ名前空間と必要な定義を持つClojureコードに名前空間を作成するだけでこの問題を回避しましたが、これは馬鹿げたようです。たとえば、マクロにX.clojurescript.abc.yが必要な場合は、ClojureバージョンのX.clojurescript.abcでダミーyを定義する追加の名前空間をClojure側に作成します。一種のダム。

Clojurescript側で何かを参照する必要があるマクロはどうやって処理しますか?

+0

パラメータとしてclojurescriptから必要なものをすべて取るようにマクロを作成します。いくつかのコードを追加することができれば、あなたの明確な質問にもっと簡単に答えることができます – Ankur

+2

私はあなたの質問を理解するとは思わない。あなたのマクロは、* clojurescriptで評価されるコードを生成する*必要があります。だから、もしあなたがclourescript defを参照しなければならないのであれば、マクロの展開でシンボルを生成するのに十分ではありませんか? – KIMA

+0

'Clojurescript側の何かを参照する'あなたはマクロ展開時にこれを必要とするか、これは出力コードで出力されるものでしょうか? – Ankur

答えて

6

マクロが定義時に特定の名前空間を必要とするのは、マクロがその名前空間のコードを使用して戻す記号のリストを生成する場合だけです。あなたはREPLでこれらの例と一緒に従うことができます

:FOOの定義はバーが定義された名前空間のfooを呼び出す

(foo :a) 

なくても、コンパイルします

(defmacro foo 
    [a] 
    `(bar/bar ~a)) 

は今ので失敗しますバーの名前空間、または関数バーがまだ定義されていない

(ns bar) 
(defn bar 
    [x] 
    [x x]) 

はバーの名前空間にバーを定義

(ns user) 
(foo :a) 

=> [::A]バーがfooの定義時に存在する必要がないことを

注意してください。実際、ネームスペースはfooの定義時に存在する必要はありません。

+0

コンパイルは一つのことですが、ClojureScript側でライブラリを必要とするのはどうですか?上記の例では、fooマクロを呼び出すClojureScriptモジュールにbar名前空間を必要とする必要があるようです。つまり、呼び出し側モジュールがマクロの実装の詳細を知っている必要があります。 –

+0

私が言及した問題の例は、Hiccupsライブラリによって経験されています。ここでは解決策が分かります。https://github.com/teropa/hiccups#usage –

+1

これはClojurescriptの実装上の根本的な問題だと思います。私はそれを扱う最良の方法であると信じていることを示唆していますが、理想的ではないことを理解しています。しかし基本的に、これは純粋なクローゼットコードでマクロを使う方法と変わりありません。マクロは呼び出し時にシンボルを生成する関数を探します。 – noisesmith

関連する問題