2014-08-30 45 views
1

我有一個cljx中的圖形程序的代碼庫,它被編譯爲Clojure和ClojureScript。在cljx中使用Clojure宏

我現在想介紹我的第一個宏。

(defmacro optional-styled-primitive [args body] 
    (let [extra (conj args 'style)] 
    `(fn (~extra (->SShape ~'style ~body)) 
      (~args (->SShape {} ~body)) 
    ) 
    ) 
) 

該宏的目的是獲取參數列表以及使用這些參數生成幾何圖形的表達式。並返回一個帶有兩個arities的函數:其中一個採用可選的樣式參數。這個宏然後被用在它所定義的文件中,以製作許多其他可以選擇樣式的函數。例如:

(def square (optional-styled-primitive [n] [[0 0] [0 n] [n n] [n 0]])) 

但是,引入這個宏很明顯地破壞了編譯的ClojureScript階段。

我不明白的是該怎麼做。在線討論討論ClojureScript需要使用:require-macros,但我從來沒有實際導出或需要這個宏的任何地方。我只是想在它定義的地方使用它。那麼我怎麼能在文件中間告訴編譯器在ClojureScript編譯器之前使用Clojure來擴展這個宏呢?

+0

'defmacro'告訴編譯器在編譯其餘代碼之前展開宏。即使在Clojurescript中,你也應該只寫'defmacro'然後使用宏。我懷疑還有其他事情正在發生。 – 2014-09-02 07:42:45

回答

0

好的。

我已經取得了一些進展。

這就是我所做的。

1)我重構我的宏定義伸到macros.cljx

2名爲獨立的文件),在該文件中,我用的是宏,我這樣做。 (不同的需要CLJ和cljs)

(#+clj :require #+cljs :require-macros 
    [myapp.macros :refer [optional-styled-primitive]]) 

3)我更新了我的leiningen project.clj文件:

:cljsbuild {:builds [{ 
    :source-paths ["target/classes" "src-cljs" ] ... 

這裏最重要的事情,我補充說: 「目標/班」,也就是輸出-path其中,cljx將其創建的clj文件放入cljsbuild源路徑。這是cljsbuild進程可以在宏定義中找到clj文件的地方。

我不確定這是否是解決問題的正確或有原則的方法。但它現在似乎正在工作(除非我困惑的東西)。

+1

是的,這基本上是正確的:如果cljx將發出包含從ClojureScript中使用的宏的代碼,您將始終需要將cljx的輸出路徑包含在cljsbuild源路徑中。 – cemerick 2014-12-21 13:13:54