TL;DR I have an extra clojure.core/fn wrapped around the form I want
returned from my macro. This is my first macro and I'm not sure what's
wrong, even though the macro "works."
I'm trying my first attempt at a macro by trying to save myself from
having to type "sql/with-connection db" for every time I want to
invoke a database command. I figure I can type "dc" (short for
"database connection") instead.
I'm doing something wrong but I've tried a few iterations of ', `, ~,
and ~@ the closest I got was this one:
(def db {:classname "org.postgresql.Driver"
:subprotocol "postgresql"
:subname (str "//localhost:5432/shouter")
:user "username"
:password "1234"})
(defmacro dc
[sql-cmd]
(list 'sql/with-connection 'db
sql-cmd))
This macro works in that it actually invokes the form I want, but when
I run macroexpand on it I have an extra clojure.core/fn wrapped around
my command, and when I compare that output to the "when" macro (which
does not have the clojure.core/fn wrapper that I can see), I think
I've got it wrong.
user> (macroexpand '(when (pos? a) (println "positive") (/ b a)))
(if (pos? a) (do (println "positive") (/ b a)))
user> (macroexpand '(dc (sql/create-table :testing [:data :text])))
(clojure.java.jdbc.internal/with-connection* db (clojure.core/fn []
(sql/create-table :testing [:data :text])))
I've also tried it with "& args" so I don't have to put my
"sql/create-table ..." form in parens, but it seems to work even worse
(I've still got the extra clojure.core/fn and now parens are around
the args).
(defmacro dc1
[sql-cmd & args]
(list 'sql/with-connection 'db
sql-cmd args))
user> (macroexpand '(dc1 sql/create-table :testing [:data :text]))
(clojure.java.jdbc.internal/with-connection* db (clojure.core/fn []
sql/create-table (:testing [:data :text])))
I also tried this variation, which works but instead of returning the
status of the database command (0) as dc did, it returns the last arg
passed in, [:data :text].
(defmacro dc2
[sql-cmd & args]
`(sql/with-connection db
~sql-cmd ~@args))
user> (macroexpand '(dc2 sql/create-table :testing [:data :text]))
(clojure.java.jdbc.internal/with-connection* user/db (clojure.core/fn
[] sql/create-table :testing [:data :text]))
Any ideas on where I'm specifically going wrong, or where to read
further on macros (preferably simple examples)?
Thanks,
Peter
--
The king’s heart is like a stream of water directed by the Lord; He
guides it wherever He pleases.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en