2016-05-03 9 views
1

(constantly (throw (Exception. "Don't call me")))私はconstantlyためにClojureのdocsに基づいて、これを実行することが期待方法です:引数を無視して常に例外をスローする関数を作成する方法は?

(constantly x)

引数と戻りxの任意の数を取る関数を返します

しかし、私が常にスローするモック関数を作成しようとすると、すぐに例外がスローされ、ここで関数を定義しようとしています。 constantlyはすぐに身体を評価し、結果をキャッシュするはずですか?私はCの恐ろしい未定義の行動(この場合、「すべての賭けはあなたが副作用に頼ってしまうとオフになる」)に相当するものを実行していますか?

user=> (constantly (throw (Exception. "but not right now"))) 

Exception but not right now user/eval8734 (form-init1747541642059004341.clj:1) 
user=> (repeatedly (throw (Exception. "but not right now"))) 

Exception but not right now user/eval8736 (form-init1747541642059004341.clj:1) 

コールバック関数をテストでモックして呼び出すとエラーになることはありますか?

+0

をスナップああ、私は問題を参照して、 '((例外をスロー「ではなく、今」)。)' expressioですnは例外をスローします。定数または評価する式ではありません。 「絶えず」ここで働くつもりはない... –

答えて

6

constantlyは関数です。その引数を評価し、評価された結果を返す関数を返します。あなたはすべての引数を無視し、いくつかの表現にそれが呼び出されるたびに評価する関数を書きたい場合は、このような何かを行うことができます。

(fn [& _] (throw (Exception. "Don't call me"))) 

例:

((fn [& _] (throw (Exception. "Don't call me"))) :foo :bar) 
;=> java.lang.Exception: Don't call me 

また書くことができますその引数を無視する関数を作成するマクロ:

(defmacro ignore-args [& exprs] 
    `(fn ~'[& _] [email protected])) 

例:

((ignore-args (throw (Exception. "Don't call me"))) :foo :bar) 
;=> java.lang.Exception: Don't call me 

このようなマクロの有用性は完全にはわかりませんが、説明的な名前(この場合はignore-args)を使用すると、入力には(fn [& _] ,,,)より長くかかり、意味論的意味あなただけ常に例外をスローする機能が必要な場合

1

、あなたがこれを行うことができます:

(defn blowup [& args] (throw (Exception. "I just blew up"))) 

あなたはオンデマンドでそれらを作るための方法を探しているなら、代わりにこれを試してみてください。

(defn explosives-factory [e] (fn [& args] (throw e))) 

あなたがここに実際にそれを見ることができます。

user=> (defn explosives-factory [e] (fn [&args] (throw e))) 
#'user/explosives-factory 
user=> (def blowup (explosives-factory (Exception. "Boom!"))) 
#'user/blowup 
user=> (blowup 123) 

Exception Boom! sun.reflect.NativeConstructorAccessorImpl.newInstance0 (NativeConstructorAccessorImpl.java:-2) 
関連する問題