Codebase list kitchensink-clojure / 1f24304
(maint) add assoc-if-new assoc-if-new behaves as assoc does only if the key does not exist in the map already. If the key already exists in the map, it's a noop. Wyatt Alt 7 years ago
2 changed file(s) with 25 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
10301030 []
10311031 (with-open [s (java.net.ServerSocket. 0)]
10321032 (.getLocalPort s)))
1033
1034 (defmacro assoc-if-new
1035 "Assocs the provided values with the corresponding keys if and only
1036 if the key is not already present in map."
1037 [map key val & kvs]
1038 {:pre [(even? (count kvs))]}
1039 (let [deferred-kvs (vec (for [[k v] (cons [key val] (partition 2 kvs))]
1040 [k `(fn [] ~v)]))]
1041 `(let [updates# (for [[k# v#] ~deferred-kvs
1042 :when (= ::not-found (get ~map k# ::not-found))]
1043 [k# (v#)])]
1044 (merge ~map (into {} updates#)))))
737737 (let [open-ports (set (take 60000 (repeatedly open-port-num)))]
738738 (is (every? pos? open-ports))
739739 (is (not (contains? open-ports port-in-use)))))))
740
741 (deftest assoc-if-new-test
742 (testing "assoc-if-new assocs appropriately"
743 (is (= {:a "foo"}
744 (assoc-if-new {:a "foo"} :a "bar")))
745 (is (= {:a "bar" :b "foo"}
746 (assoc-if-new {:b "foo"} :a "bar")))
747 (is (= {:a "foo" :b "bar"}
748 (assoc-if-new {} :a "foo" :b "bar")))
749 (is (= {:a "foo" :b nil}
750 (assoc-if-new {:b nil} :a "foo" :b "bar")))
751 (is (= {:a "foo" :b "baz"}
752 (assoc-if-new {:b "baz"} :a "foo" :b "bar")))))