Created
May 30, 2014 21:15
-
-
Save ctford/fe2282c04482b23bde26 to your computer and use it in GitHub Desktop.
An alternative implementation of map that won't silently return nils for missing keys.
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
(ns strict-map.map) | |
(deftype StrictMap [inner] | |
clojure.lang.IPersistentMap | |
(assoc [this k v] | |
(StrictMap. (.assoc inner k v))) | |
(assocEx [this k v] | |
(StrictMap. (.assocEx inner k v))) | |
(without [this k] | |
(StrictMap. (.without inner k))) | |
java.lang.Iterable | |
(iterator [this] | |
(.iterator inner)) | |
clojure.lang.Associative | |
(containsKey [this k] | |
(.containsKey inner k)) | |
(entryAt [this k] | |
(.entryAt inner k)) | |
clojure.lang.IPersistentCollection | |
(count [this] | |
(.count inner)) | |
(cons [this x] | |
(StrictMap. (.cons inner x))) | |
(empty [this] | |
(.empty inner)) | |
(equiv [this other] | |
(and (map? other) (= (seq other) (seq inner)))) | |
clojure.lang.Seqable | |
(seq [this] | |
(.seq inner)) | |
clojure.lang.IFn | |
(invoke [this k] | |
(.invoke inner k)) | |
(invoke [this k default] | |
(.invoke inner k default)) | |
(applyTo [this args] | |
(.applyTo inner args)) | |
clojure.lang.ILookup | |
(valAt [this k] | |
(let [v (get inner k)] | |
(cond (not (contains? inner k)) | |
(throw (new Exception (str "Key '" k "' not found in strict map '" inner "'."))) | |
(map? v) | |
(StrictMap. v) | |
:otherwise | |
v))) | |
(valAt [this k default] | |
(let [v (get inner k)] | |
(cond (not (contains? inner k)) | |
default | |
(map? v) | |
(StrictMap. v) | |
:otherwise | |
v)))) | |
(defn strict | |
"Convert an ordinary map into one that throws an Exception if an unknown key is requested." | |
[m] (StrictMap. m)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thinking it should wrap the .inner call with a new StrictMap.