sventechie
sventechie

Reputation: 1847

How can I add a second parameter to a macro in Clojure?

I have the following Clojure wrapping macro with 1 parameter:

(defmacro with-init-check
"Wraps the given statements with an init check."
[body]
`(if (initialized?)
  ~body
  (throw (IllegalStateException. "GeoIP db not initialized."))))

I want to add ip-version to it so I can check if just :IPv6 or :IPv4 is initialized. However the parameter does not get passed through when I try this:

(defmacro with-init-check
  "Wraps the given statements with an init check."
  [ip-version body]
  `(if (initialized? ip-version)
    ~body
    (throw (IllegalStateException. "GeoIP db not initialized."))))

When I use it like this, I get "no such var" at the "if-let [location..." line:

(defn- lookup-location
  "Looks up IP location information."
  [ip ip-version]
  (with-init-check ip-version
    (if-let [location (get-location ip ip-version)]
  {:ip ip
   :countryCode (.countryCode location)
   :countryName (.countryName location)
   :region (.region location)
   :city (.city location)
   :postalCode (.postalCode location)
   :latitude (.latitude location)
   :longitude (.longitude location)
   :dma-code (.dma_code location)
   :area-code (.area_code location)
   :metro-code (.metro_code location)})))

How can I get the ip-version to the initialized? function?

Upvotes: 0

Views: 81

Answers (1)

user1804599
user1804599

Reputation:

Unquote it with ~:

(defmacro with-init-check
  "Wraps the given statements with an init check."
  [ip-version body]
  `(if (initialized? ~ip-version) ; unquoted with ~
     ~body
     (throw (IllegalStateException. "GeoIP db not initialized."))))

Deducing from your docstring, you probably also want to allow multi-expression bodies and unquote-splice them in a do expression:

(defmacro with-init-check
  "Wraps the given statements with an init check."
  [ip-version & body] ; multi-expression bodies with &
  `(if (initialized? ~ip-version)
     (do ~@body) ; unquote-spliced with ~@
     (throw (IllegalStateException. "GeoIP db not initialized."))))

Upvotes: 4

Related Questions