late-bind custom readers

this much-less-invasively fixes the problem I was trying to fix in #48.

In resources/data_readers.clj we direct clojure to use these functions
in honeysql.types to read tagged literals in EDN as SqlCalls, SqlRaws,
and SqlParams. Clojure does this by making a permanent binding to the
Vars for these functions which exist in honeysql.types when it starts
up. The trouble is that if someone is doing REPL-driven development
and calls clojure.tools.namespace.repl/refresh, those vars will be
wholely recreated, along with the deftype classes they point to.

This means that if there's a sql/call in a piece of edn we're reading,
we'll get an instance of the *old* SqlCall class, but if someone just
calls honeysql.types/call they'll get an instance of the *new* class.
These won't match up, and this'll cause some of the tests in core_tests
to fail.

This patch works around that by causing these custom reader functions
to resolve the helpers they call each time they are called, so we
always create instances of the new types if they've been redefined.

Again, this has basically zero effect on the end user, but it removes
a pain-point for someone using REPL-driven development to work on
honeysql itself.
This commit is contained in:
Mike Blume 2015-03-11 10:05:24 -07:00
parent 941a5b708a
commit 5329d020e6

View file

@ -18,7 +18,8 @@
(SqlCall. name args nil)) (SqlCall. name args nil))
(defn read-sql-call [form] (defn read-sql-call [form]
(apply call form)) ;; late bind so that we get new class on REPL reset
(apply (resolve `call) form))
(defmethod print-method SqlCall [^SqlCall o ^java.io.Writer w] (defmethod print-method SqlCall [^SqlCall o ^java.io.Writer w]
(.write w (str "#sql/call " (pr-str (into [(.name o)] (.args o)))))) (.write w (str "#sql/call " (pr-str (into [(.name o)] (.args o))))))
@ -42,7 +43,8 @@
(SqlRaw. (str s) nil)) (SqlRaw. (str s) nil))
(defn read-sql-raw [form] (defn read-sql-raw [form]
(raw form)) ;; late bind, as above
((resolve `raw) form))
(defmethod print-method SqlRaw [^SqlRaw o ^java.io.Writer w] (defmethod print-method SqlRaw [^SqlRaw o ^java.io.Writer w]
(.write w (str "#sql/raw " (pr-str (.s o))))) (.write w (str "#sql/raw " (pr-str (.s o)))))
@ -69,7 +71,8 @@
(.name param)) (.name param))
(defn read-sql-param [form] (defn read-sql-param [form]
(param form)) ;; late bind, as above
((resolve `param) form))
(defmethod print-method SqlParam [^SqlParam o ^java.io.Writer w] (defmethod print-method SqlParam [^SqlParam o ^java.io.Writer w]
(.write w (str "#sql/param " (pr-str (.name o))))) (.write w (str "#sql/param " (pr-str (.name o)))))