clojure - Use function in macro -
i have function load correctly namespace :
(defn load-module [module-name] (use module-name) )
and "equivalent" macro doesn't work :
(defmacro load-module-macro [module-name] `( (use '~module-name) ) )
i don't understand problem.
moreover, want use macro load module choose in configuration. in config.clj define var namespace of logger module contains "save-data" function. want load specified logger in core program. can choose logger use directly in configuration file (logger on disk, logger in database...). best way ?
edit :
error message
illegalargumentexception don't know how create iseq from: java.lang.character clojure.lang.rt.seqfrom (rt.java:505)
no, in fact don't want use "use" directly in code @ all. use modifies entire namespace called in , break code in ways hardly predictable.
instead should is: implement logging interface (protocol), write "meta-constructor" dispatches whatever set in config.clj keyword. code example
(defprotocol ilog (save-data [this msg] "logs message in msg.")) (defn create-file-log "returns object implementing ilog, opens , flushes java.io.file file." [file] (let [f ... ;; create file writer here ] (reify ilog (save-data [this msg] ;; write code writes data file here )))) ;; create other implementations database here or elsewhere (defn create-log "creates log of of type passed in type-kw." [type-kw] (case type-kw :file (create-file-log "./app-log.txt") ;; other types ))
now invoke create-log whatever keyword set in config file , pass returned object around functions need logging. obviously, def global object don't recommend that.
eventually don't want set keyword (type-kw) desired logging method in config, other parameters file-name or database uri can pass like
{:log-method :file :data {:fname "app-log.txt"}} or {:log-method :db :data {:uri "....
...to create-log function uses structure parameters reify constructors create-file-log, create-db-log, etc.
edit: because don't switch statement, here how multi-methods:
(defmulti create-log :logging-method) (defmethod create-log :file [arg-map] (let [file (java.io.file. (:fname arg-map))] (if (.exists file) ...
then have entry in config.clj
{... :log {:logging-method :file :fname "./log-file.txt"}}
to create new logging type have imagine argument map 1 above , constructor method create-log.
Comments
Post a Comment