Frantisek Sodomka wrote:
> Hello!
> It is very common pattern to include parts of code which are used for
> specific purposes - for example debugging, logging, etc. While these parts
> can be used when developing code, they can be removed from finished
> application. One way is to comment these parts out, when we are done.
> Since commenting can be tedious and error-prone, it makes sense to make a
> macro for this:
>
> (def *debug* true)  ; true/false
>
> (defmacro debug [& body]
>    (if *debug*
>      `(do [EMAIL PROTECTED])))
>
>
> (defn myfn [x]
>    (debug
>      (println "Print some debug info...")
>      (print "x = ") (prn x))
>    (* 2 x))
>
> (myfn 5)
>
>
> To extend this idea little further, lets define "code sections":
>
> (def *section-tags* {:debug true :log0 true :log1 false})
>
> (defmacro section [tag & body]
>    (if (*section-tags* tag)
>      `(do [EMAIL PROTECTED])))
>
>
> (defn myfn [x]
>    (section :debug
>      (println "debugging info...")
>      (print "x = ") (prn x))
>    (section :log0
>      (println "logging info..."))
>    (section :log1
>      (println "detailed logging info..."))
>    (* 2 x))
>
> (myfn 10)
>
>
> Latest addition for libs to boot.clj also has this pattern, when using
> *loading-verbosely* flag.
>
> Any comments welcome, Frantisek

I like something along the lines of Python decorators[1] as
that keeps the logic of the function from being lost in the
instrumentation code.

E.g.
    (def *verbose* true)

    (defn print-decorate [f]
      (fn [& args]
        (println f "called with" args)
        (apply f args)))

    (defn foo [x] (* 2 x))

    (when *verbose*
      (def foo (print-decorate foo)))

With *verbose* true:

    user=> (load-file "foo.clj")
    #'user/foo
    user=> (foo 2)
    [EMAIL PROTECTED] called with (2)
    4

With *verbose* false:

    user=> (load-file "foo.clj")
    nil
    user=> (foo 2)
    4

Perhaps this approach can be improvised further but
I myself am somewhat of a Clojure noob.

I suspect the boot.clj code (especially in the early part of
 the file) may not be most ideomatic Clojure code as
Clojure is still booting itself.

On a somewhat related note. Getting the function name at the
Clojure prompt seems to work:

    user=> (:name (meta (var foo)))
    foo

However if I try to improvise print-decorate by putting
in the above approach, I get an exception while loading
the file.

(defn print-decorate [f]
  (fn [& args]
    (println (:name (meta (var f))) "called with" args)
    (apply f args)))

clojure.lang.Compiler$CompilerException: foo.clj:5: Unable to resolve
var: f in
this context

Could someone explain what I am doing wrong here?
How can I get the function name at runtime in print-decorate?

Full exception log below.

Parth
[1] http://www.ibm.com/developerworks/linux/library/l-cpdecor.html

user=> (load-file "foo.clj")
java.lang.Exception: Unable to resolve var: f in this context
clojure.lang.Compiler$CompilerException: foo.clj:5: Unable to resolve
var: f in this context
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3821)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyze(Compiler.java:3627)
        at clojure.lang.Compiler.access$100(Compiler.java:37)
        at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2630)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3816)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyze(Compiler.java:3627)
        at clojure.lang.Compiler.access$100(Compiler.java:37)
        at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2630)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3816)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyze(Compiler.java:3627)
        at clojure.lang.Compiler.access$100(Compiler.java:37)
        at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2630)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3816)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyze(Compiler.java:3627)
        at clojure.lang.Compiler.access$100(Compiler.java:37)
        at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:
3340)
        at clojure.lang.Compiler$FnMethod.parse(Compiler.java:3187)
        at clojure.lang.Compiler$FnMethod.access$1200(Compiler.java:
3098)
        at clojure.lang.Compiler$FnExpr.parse(Compiler.java:2729)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3812)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3804)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyze(Compiler.java:3627)
        at clojure.lang.Compiler.access$100(Compiler.java:37)
        at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:
3340)
        at clojure.lang.Compiler$FnMethod.parse(Compiler.java:3187)
        at clojure.lang.Compiler$FnMethod.access$1200(Compiler.java:
3098)
        at clojure.lang.Compiler$FnExpr.parse(Compiler.java:2729)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3812)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3804)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.access$200(Compiler.java:37)
        at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:
335)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3814)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3804)
        at clojure.lang.Compiler.analyze(Compiler.java:3654)
        at clojure.lang.Compiler.analyze(Compiler.java:3627)
        at clojure.lang.Compiler.eval(Compiler.java:3851)
        at clojure.lang.Compiler.load(Compiler.java:4136)
        at clojure.lang.Compiler.loadFile(Compiler.java:4103)
        at clojure.lang.RT$3.invoke(RT.java:285)
        at user.eval__2409.invoke(Unknown Source)
        at clojure.lang.Compiler.eval(Compiler.java:3847)
        at clojure.lang.Repl.main(Repl.java:75)
Caused by: java.lang.Exception: Unable to resolve var: f in this
context
        at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:
457)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:3814)
        ... 50 more


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to