-?> と .?.
nilを返す関数
こんな階乗関数を書いたとします。
(defn fact [n] (when (>= n 0) (loop [n n acc 1] (if (< n 2) acc (recur (dec n) (* acc n))))))
最初に引数チェックを行い、引数が0以上の時のみ処理をおこないます。引数が負数だと何もせず何も返さないので評価値は nil になります。
(fact 10) ;=> 3628800 (fact -1) ;=> nil
これを使ってプログラムを組んでみました。
(-> 10 fact inc (str " finished")) ;;=> "3628801 finished" (-> -1 fact inc (str " finished")) ;;=> java.lang.NullPointerException ...
階乗の結果をインクリメントして、その結果に finished をくっつけたものが式全体の評価値になります。二つめの例では fact に渡されるのが負数のため fact の評価値が nil になり、次の inc で null例外が発生しています。
そこで -?> を使う
こういう場合に -?> を使うと例外発生を抑制できます。
(use '[clojure.contrib.core :only (-?>)]) (-?> 10 fact inc (str " finished")) ;;=> "3628801 finished" (-?> -1 fact inc (str " finished")) ;;=> nil
-?> を使うと式の途中で評価値 nil になった時点で評価を終了し、全体の評価値が nil になります。上の例では fact の結果が nil に成ったところで評価が終了しています。その後の inc や str は評価されません。
なお評価値に nil が現れなけば、-?> は -> と同じ結果になります。
一方 -?>> は用意されていませんでした。-?> を真似れば自分で作れそうな気がします。どちらかというと -> よりも ->> のほうが使う場面が多いので -?>> の方がむしろ必要かもしれません。
でもこれ必要?
どうもこの -?> を使う状況というのは好ましくない状況に思えます。
「どこかで nil になるかもしれないけど、隠蔽しちゃえ」ということですから、それってなんかエラー管理がいい加減な気がするのですが。
ある種の脱出ロジックには使えるかもしれませんが、それもちょっと好ましいコードとは言えないですよね。
.?. もあるよ。
javaメソッドのチェーンを行う「..」に対応した「.?.」もあります。
こちらは -?> よりも使える場面が限られていそうです。