Created
January 14, 2013 13:03
-
-
Save bouzuya/4529917 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(use 'clojure.test) | |
(with-test | |
(defn f | |
[& {:as options}] | |
options) | |
(is (nil? (f))) | |
(is (thrown? IllegalArgumentException (f nil))) | |
(is (thrown? IllegalArgumentException (f :a))) | |
(is (= (f nil nil) {nil nil})) | |
(is (= (f :a \a) {:a \a})) | |
(is (= (f :a \a :b \b) {:a \a :b \b})) | |
(is (= (f :a \a :b \b :c \c) {:a \a :b \b :c \c}))) | |
(with-test | |
(defn g | |
[& {:as options :or {a \0 b \1}}] | |
options) | |
(is (nil? (g))) ; oh... | |
(is (thrown? IllegalArgumentException (g nil))) | |
(is (thrown? IllegalArgumentException (g :a))) | |
(is (= (g nil nil) {nil nil})) | |
(is (= (g :a \a) {:a \a})) | |
(is (= (g :a \a :b \b) {:a \a :b \b})) | |
(is (= (g :a \a :b \b :c \c) {:a \a :b \b :c \c}))) ; oh... | |
(with-test | |
(defn h | |
[& {:keys [a b] :or {a \0 b \1}}] ; oh... | |
{:a a :b b}) | |
(is (= (h) {:a \0 :b \1})) | |
(is (thrown? IllegalArgumentException (h nil))) | |
(is (thrown? IllegalArgumentException (h :a))) | |
(is (= (h nil nil) {:a \0 :b \1})) | |
(is (= (h :a \a) {:a \a :b \1})) | |
(is (= (h :a \a :b \b) {:a \a :b \b})) | |
(is (= (h :a \a :b \b :c \c) {:a \a :b \b}))) | |
(with-test | |
(defn i | |
[& {:as options}] | |
(merge {:a \0 :b \1} | |
options)) | |
(is (= (i) {:a \0 :b \1})) | |
(is (thrown? IllegalArgumentException (i nil))) | |
(is (thrown? IllegalArgumentException (i :a))) | |
(is (= (i nil nil) {nil nil :a \0 :b \1})) ; oh... | |
(is (= (i :a \a) {:a \a :b \1})) | |
(is (= (i :a \a :b \b) {:a \a :b \b})) | |
(is (= (i :a \a :b \b :c \c) {:a \a :b \b :c \c}))) ; oh... | |
(with-test | |
(defn j | |
[& {:as options}] | |
(let [default {:a \0 :b \1}] | |
(into {} (filter (comp (set (keys default)) key) | |
(merge default options))))) | |
(is (= (j) {:a \0 :b \1})) | |
(is (thrown? IllegalArgumentException (j nil))) | |
(is (thrown? IllegalArgumentException (j :a))) | |
(is (= (j nil nil) {:a \0 :b \1})) | |
(is (= (j :a \a) {:a \a :b \1})) | |
(is (= (j :a \a :b \b) {:a \a :b \b})) | |
(is (= (j :a \a :b \b :c \c) {:a \a :b \b}))) | |
(with-test | |
(defn apply-defaults | |
[values defaults] | |
(->> | |
(apply hash-map values) | |
(merge defaults) | |
(filter (comp (set (keys defaults)) key)) | |
(remove (comp nil? val)) | |
(into {}))) | |
(is (thrown? IllegalArgumentException (apply-defaults [nil] {:a \0 :b \1}))) | |
(are [values expected] | |
(= (apply-defaults values {:a \0 :b \1}) expected) | |
nil {:a \0 :b \1} | |
[] {:a \0 :b \1} | |
[nil nil] {:a \0 :b \1} | |
[:a \a] {:a \a :b \1} | |
[:a \a :b \b] {:a \a :b \b} | |
[:a \a :b \b :c \c] {:a \a :b \b}) | |
(are [values expected] | |
(= (apply-defaults values {:a \0 :b \1 :c nil}) expected) | |
[:a \a] {:a \a :b \1} | |
[:a \a :b \b] {:a \a :b \b} | |
[:a \a :c \c] {:a \a :b \1 :c \c} | |
[:a \a :b \b :c nil] {:a \a :b \b} | |
[:a \a :b \b :d \d] {:a \a :b \b} | |
[:a \a :b \b :c \c] {:a \a :b \b :c \c})) | |
(with-test | |
(defn k | |
[& options] | |
(apply-defaults options {:a \0 :b \1})) ; ok! | |
(is (= (k) {:a \0 :b \1})) | |
(is (thrown? IllegalArgumentException (k nil))) | |
(is (thrown? IllegalArgumentException (k :a))) | |
(is (= (k nil nil) {:a \0 :b \1})) | |
(is (= (k :a \a) {:a \a :b \1})) | |
(is (= (k :a \a :b \b) {:a \a :b \b})) | |
(is (= (k :a \a :b \b :c \c) {:a \a :b \b}))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Clojure での省略可能引数の書き方について考えてみた。
最終的には
apply-defaults
を定義して、それに処理させるk
に落ち着いた。apply-defaults
は指定可能な引数の制限と、val が nil のものの削除と、デフォルト値の設定を行う。色々やりすぎているが、これくらいの方が使いやすいと思う。良い名前が思い浮かばないので、ひとまずapply-defaults
にしている。引数の制限や nil 値の削除が不要なら
i
の(merge defaults options)
で十分で、これなら関数も不要だと思う。