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}))) | |
Author
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)で十分で、これなら関数も不要だと思う。