2017-05-06 5 views

答えて

1

我々は任意の値に3を追加するマクロテストしたいとします

(defmacro iiinc [x] 
    `(+ 3 ~x)) 

よりもむしろREPLでの作業を、私は通常のコードを開発するために私の好きなテキストエディタ/ IDEを使用することを好む、とthe lein test-refresh pluginを使用私のユニットテストを継続的に実行するしかし、新しいマクロを繰り返し開発するためにmacroexpand-1を使用しようとすると、これは機能しません。

問題はmacroexpand-1deftestマクロの間に多少の矛盾があるようです。だから、解決策は(deftest ...)フォームの中にmacroexpand-1を使用しないことです。しかし、ユニットテストのソースファイルにまだ残っていても、deftestの外ではうまく動作します。ここでは例です:

; source file tst.clj.core 

(newline) 
(println "This works when not in (deftest ...)") 
(println "(macroexpand-1 '(iiinc 2)) =>" (macroexpand-1 '(iiinc 2))) 

(deftest t-stuff 
    (newline) 
    (println "But it is broken inside (deftest ...)") 
    (println "(macroexpand-1 '(iiinc 2)) =>" (macroexpand-1 '(iiinc 2))) 

    (newline) 
    (println "However, we can use the macro itself fine in our tests") 
    (println " (iiinc 2) =>" (iiinc 2)) 
    (is (= 5 (iiinc 2)))) ; unit test works fine 

上記の結果は次のとおりです。

This works when not in (deftest ...) 
(macroexpand-1 '(iiinc 2)) => (clojure.core/+ 3 2) 

Testing tst.clj.core 

But it is broken inside (deftest ...) 
(macroexpand-1 '(iiinc 2)) => (iiinc 2) 

However, we can use the macro itself fine in our tests 
    (iiinc 2) => 5 

Ran 1 tests containing 1 assertions. 
0 failures, 0 errors. 
+1

良い答えですが、この内容の一部はあなた自身が質問していることは、あなたがしようとしていることが機能していないことを説明しているからです。この答えのコンテキストがなければ、誰もあなたの非常に省略された質問に答えることができませんでした。 – amalloy

3

問題が*ns*がバインドされている間deftestの外あなたの表現は、コンパイル時に実行されていることである、との内deftestこれらは実行時に後で実行されますが、*ns*がバインドされていません。

なぜこの点が重要ですか? macroexpandは、現在の名前空間のシンボルiiincを解決して、マクロであるかどうかを判断し、それがマクロである場合にその定義を見つけて呼び出す必要があるためです。コンパイル時にmacroexpandが動作しているが、実行時には動作していないことがわかります。

解決策は何ですか。確かにコンパイル時にテストを実行しないでください!代わりに、フォームの名前空間を適切に修飾して、*ns*のコンパイル時の利便性に依存しないようにする必要があります。使用する:あなたは、しかし、適切なソリューションは、後の評価のために意図されているフォームを引用するときに常にはちょうどあなたがマクロを書くときのように、何をすべきかを行うことです

(deftest t-stuff 
    (println "(macroexpand-1 '(my.ns/iiinc 2)) =>" (macroexpand-1 '(my.ns/iiinc 2))))) 

を書き込むことによって、手動でこれを行うことができます構文引用符ではなく、通常の引用符ではありません。コンパイラがコンパイル時に意図した名前空間を見つけ出し、実行時にまだそれが存在するようにフォームに挿入します:

(deftest t-stuff 
    (println "(macroexpand-1 `(iiinc 2)) =>" (macroexpand-1 `(iiinc 2))))) 
関連する問題