On Thu, Jun 25, 2009 at 10:54 PM, Jurjen<jurjen.hait...@gmail.com> wrote: > > Essentially my new version of defn is a basic wrapper around defn: > (defmacro mkfn [nm args func] > (list 'defn nm {:source (str "(mkfn " nm " " args " " func ")")} > args func)) > > so when you do (mkfn test1 [a b] (+ a b)) you get out a function test1 > with a metadata :source tag (meta (var test1)) > {:ns #<Namespace user>, :name test1, :file "NO_SOURCE_PATH", :line > 439, :arglists ([a b]), :tag "sometag", :source "(mkfn test1 [a b] (+ > a b))"} > > I tried to override the print-dup for clojure.lang.Fn to check for > the :source meta-data tag, but I keep getting NullPointerExceptions. > Anyone got any ideas? Am I missing something obvious?
It may not be obvious, but your mkfn macro is setting the metadata of the Var that contains the fn, not the fn itself. This is why to see the meta you had to say (meta (var test1)) intead of just (meta test1). This also means that if you do (pr-str test1), pr-str has no way to get to the metadata. When this expression is evaluated, the symbol 'test1' is resolved to the Var, then the Var is deref'ed to the fn, and finally that fn is passed to pr-str. There's no pointer from the fn back to the Var, which makes sense if you think about anonymous fns, multiple Vars pointing to the same fn, multiple threads having different fns for the same Var, etc. I can only think of two options for you. By far the easiest would be to print the Var rather than the fn: (binding [*print-meta* true] (pr-str (var map))) or (binding [*print-meta* true] (pr-str #'map)) The other option would be to attach your metadata to the fn itself. This is a bit tricky because fns cannot be duplicated in the way that would be necessary to immutably "change" their metadata. And although you can attach metadata to a fn instance (a.k.a. closure) when it is created, there's no syntax for this. However, it is possible to do with careful use of 'proxy'. ...but even once you've captured the code used to define a fn, I'm not sure how much good it's going to do you. That metadata won't include anything about the lexical environment in which the fn was defined, the values of any closed-over locals, etc. --Chouser --~--~---------~--~----~------------~-------~--~----~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---