2016-05-13 3 views
3

私は、システムやユーザーが(例外ではない)スローされた例外をラップして、何らかの値を返すようにしたいと考えています。Clojureマクロで例外をラップする方法は?

マクロを書きましたが、動作しません。

マクロ:

(defmacro safe-fn 
    [form] 
    (try 
    `(do ~form) 
    (catch Throwable e 
     1))) 

使用:(safe-fn (throw (RuntimeException. "Try me!")))

実際の出力:RuntimeException Try me! clojure-brave-and-true.core/eval2219 (form-init6122238559239237921.clj:1)

所望の出力:1

答えて

7

マクロ評価するコードを返すだけの関数であるので、あなたはsafe-fnのように書くことができますこの:

(defmacro safe-fn 
    [form] 
    `(try 
    ~form 
    (catch Throwable ~'_ 
     1))) 

例:

(safe-fn (throw (RuntimeException. "Try me!"))) 
;=> 1 

はマクロに、具体的には、例外をキャッチするためにそれらを使用する方法の詳細についてthis questionに私の答えを参照してください。 the Tupelo libraryから

2

マクロwith-exception-defaultは、あなたが望むものを正確に行います。

デフォルト値を使用すると、例外をもたらすことができる操作を知っている時々

例外のケースでは、あなた は持ちたいです例外はデフォルト値に変換されます。それ はあなたが必要とするとき、次のとおりです。

(with-exception-default default-val & body) 
    Evaluates body & returns its result. In the event of an exception the 
    specified default value is returned instead of the exception." 

(with-exception-default 0 
    (Long/parseLong "12xy3")) 
;=> 0 

この機能は、あなたがこのように動作し 機能でしょうtupelo.parse、で良いの使用に置かれる:

(parse-long "123")     ; throws if parse error 
;=> 123 
(parse-long "1xy23" :default 666) ; returns default val if parse error 
;=> 666 
関連する問題