Permalink
Browse files

Map matching should always check for presence of key, even if wildcar…

…d matching This is a manually applied version of Jason Jackson's (jasonjckn@gmail.com) patch:


http://dev.clojure.org/jira/browse/MATCH-52

with additional code added for CLJS support.
  • Loading branch information...
1 parent 73a9d40 commit 7f73cee3f78417f1fb59bcbb4a8cda52de22efbd @lynaghk lynaghk committed with David Nolen Aug 14, 2012
Showing with 84 additions and 8 deletions.
  1. +18 −6 src/main/clojure/clojure/core/match.clj
  2. +66 −2 src/test/clojure/clojure/core/match/test/core.clj
@@ -128,12 +128,22 @@
(.valAt this k not-found)))
(defn val-at*
- ([m k] (val-at m k nil))
+ ([m k] (let [val (val-at m k ::not-found)]
+ (if (= val ::not-found)
+ (throw backtrack)
+ val)))
([m k not-found] (val-at m k not-found)))
(defn val-at-expr [& args]
- (if *clojurescript*
- `(get ~@args)
+ (if *clojurescript* ;;then we need to inline the correct behavior
+ (if (= 3 (count args))
+ `(get ~@args)
+ (let [[m k] args]
+ `(let [val# (get ~m ~k ::not-found)]
+ (if (= val# ::not-found)
+ (throw 0)
+ val#))))
+ ;;If not ClojureScript, defer to val-at*
`(val-at* ~@args)))
;; =============================================================================
@@ -849,8 +859,10 @@
(defn ^WildcardPattern wildcard-pattern
([] (WildcardPattern. '_ nil))
([sym]
- {:pre [(symbol? sym)]}
- (WildcardPattern. sym nil)))
+ {:pre [(symbol? sym)]}
+ (if (= sym '_)
+ (WildcardPattern. (gensym) nil)
+ (WildcardPattern. sym nil))))
(defn wildcard-pattern? [x]
(instance? WildcardPattern x))
@@ -1760,4 +1772,4 @@
(let [bindvars# (take-nth 2 bindings)]
`(let ~bindings
(match [~@bindvars#]
- ~@body))))
+ ~@body))))
@@ -76,11 +76,75 @@
(is (= (let [x {:a 1 :b 1}]
(match [x]
[{:a _ :b 2}] :a0
- [{:a 1 :c _}] :a1
+ [{:a 1 :b 1}] :a1
[{:c 3 :d _ :e 4}] :a2
:else []))
:a1)))
+(deftest map-pattern-match-2
+ (is (= (let [x {:a 1 :b 1}]
+ (match [x]
+ [{:a _ :b 1}] :a0
+ [{:a 1 :b _}] :a1
+ [{:c 3 :d _ :e 4}] :a2
+ :else []))
+ :a0)))
+
+(deftest map-pattern-match-3
+ (is (= (let [x {:a 1 :b 1 :c 1}]
+ (match [x]
+ [{:a _ :b 2}] :a0
+ [{:a 1 :b _}] :a1
+ [{:c 3 :d _ :e 4}] :a2
+ :else []))
+ :a1)))
+
+(deftest map-pattern-match-4
+ (is (= (let [x {:a 1 :b 1}]
+ (match [x]
+ [{:a _ :b 2}] :a0
+ [{:a _ :b _}] :a1
+ [{:c 3 :d _ :e 4}] :a2
+ :else []))
+ :a1)))
+
+(deftest map-pattern-match-5
+ (is (= (let [x {:a 1}]
+ (match [x]
+ [{:a 1 :b 1}] :a0
+ [{:a _ :b _}] :a1
+ [{:c 3 :d _ :e 4}] :a2
+ :else []))
+ [])))
+
+(deftest map-pattern-match-6
+ (is (= (let [x {:a 1 :b 1}]
+ (match [x]
+ [{:b 1}] :a0
+ [{:a _ :b _}] :a1
+ [{:a _ :b _}] :a2
+ :else []))
+ :a0)))
+
+(deftest map-pattern-match-7
+ (is (= (let [x {:a 1 :b 1}]
+ (match [x]
+ [{}] :a0
+ [{:a _ :b _}] :a1
+ [{:a 1 :b 1}] :a2
+ :else []))
+ :a0)))
+
+(deftest map-pattern-match-8
+ (is (= (let [x {:a 1 :b 1}]
+ (match [x]
+ [{:x nil :y nil}] :a0
+ [{:a _ :b _}] :a1
+ [{:a 1 :b 1}] :a2
+ :else []))
+ :a1)))
+
+
(deftest map-pattern-match-only-1
(is (= (let [x {:a 1 :b 2}]
(match [x]
@@ -650,4 +714,4 @@
[:b b] :a1
[:c] :a2
:else :a3))
- :a2)))
+ :a2)))

0 comments on commit 7f73cee

Please sign in to comment.