Skip to content

Commit 4dc388a

Browse files
puredangerstuarthalloway
authored andcommitted
CLJ-1318 - add support for destructuring namespaced keys
Signed-off-by: Stuart Halloway <stu@cognitect.com>
1 parent d00efc0 commit 4dc388a

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/clj/clojure/core.clj

+7-3
Original file line numberDiff line numberDiff line change
@@ -4040,7 +4040,8 @@
40404040
(dissoc bes (key entry))
40414041
((key entry) bes)))
40424042
(dissoc b :as :or)
4043-
{:keys #(keyword (str %)), :strs str, :syms #(list `quote %)})]
4043+
{:keys #(if (keyword? %) % (keyword (str %))),
4044+
:strs str, :syms #(list `quote %)})]
40444045
(if (seq bes)
40454046
(let [bb (key (first bes))
40464047
bk (val (first bes))
@@ -4051,14 +4052,17 @@
40514052
(next bes)))
40524053
ret))))]
40534054
(cond
4054-
(symbol? b) (-> bvec (conj b) (conj v))
4055+
(symbol? b) (-> bvec (conj (if (namespace b) (symbol (name b)) b)) (conj v))
4056+
(keyword? b) (-> bvec (conj (symbol (name b))) (conj v))
40554057
(vector? b) (pvec bvec b v)
40564058
(map? b) (pmap bvec b v)
40574059
:else (throw (new Exception (str "Unsupported binding form: " b))))))
40584060
process-entry (fn [bvec b] (pb bvec (first b) (second b)))]
40594061
(if (every? symbol? (map first bents))
40604062
bindings
4061-
(reduce1 process-entry [] bents))))
4063+
(if-let [kwbs (seq (filter #(keyword? (first %)) bents))]
4064+
(throw (new Exception (str "Unsupported binding key: " (ffirst kwbs))))
4065+
(reduce1 process-entry [] bents)))))
40624066

40634067
(defmacro let
40644068
"binding => binding-form init-expr

test/clojure/test_clojure/special.clj

+32
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,35 @@
3131
(deftest empty-list-with-:as-destructuring
3232
(let [{:as x} '()]
3333
(is (= {} x))))
34+
35+
(deftest keywords-in-destructuring
36+
(let [{:keys [:a :b]} {:a 1 :b 2}]
37+
(is (= 1 a))
38+
(is (= 2 b))))
39+
40+
(deftest namespaced-keywords-in-destructuring
41+
(let [{:keys [:a/b :c/d]} {:a/b 1 :c/d 2}]
42+
(is (= 1 b))
43+
(is (= 2 d))))
44+
45+
(deftest namespaced-keys-in-destructuring
46+
(let [{:keys [a/b c/d]} {:a/b 1 :c/d 2}]
47+
(is (= 1 b))
48+
(is (= 2 d))))
49+
50+
(deftest namespaced-syms-in-destructuring
51+
(let [{:syms [a/b c/d]} {'a/b 1 'c/d 2}]
52+
(is (= 1 b))
53+
(is (= 2 d))))
54+
55+
(deftest keywords-not-allowed-in-let-bindings
56+
(is (thrown-with-msg? Exception #"Unsupported binding key: :a"
57+
(eval '(let [:a 1] a))))
58+
(is (thrown-with-msg? Exception #"Unsupported binding key: :a/b"
59+
(eval '(let [:a/b 1] b)))))
60+
61+
(require '[clojure.string :as s])
62+
(deftest resolve-keyword-ns-alias-in-destructuring
63+
(let [{:keys [::s/x ::s/y]} {:clojure.string/x 1 :clojure.string/y 2}]
64+
(is (= x 1))
65+
(is (= y 2))))

0 commit comments

Comments
 (0)