user=> (defmacro foo [x] `(quote ~(meta &form)))
#'user/foo
user=> (foo bar)
{:line 380}
<in faddle.clj>
(ns faddle)
(defmacro foo [x] `(quote ~(meta &form)))
(defn futz [] (foo bar))
<load-file>
#'faddle/futz
user=>
<change-repl-to-file-ns>
faddle=> (futz)
{:line 3}
No. It looks like the &form meta contains only the :line key.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
I guess we ask nicely for it to be added to the &form metadata in 1.3. :)
Interestingly, extracting the correct line number in cases of
multi-line forms is already handled:
(ns faddle)
(defmacro foo [x] `(quote ~(meta (second &form))))
(defn futz [] (foo
(bar baz)))
faddle=> (futz)
{:line 4}
Not 3 or nil, 4. The subform (bar baz) has its own metadata with the
correct line number. Since new, non-blank lines almost always start
with an open parenthesis after the leading whitespace, pretty much any
error can be localized to the correct line number even if the macro
body spans multiple lines. Furthermore, the exception lines tend to
contain a literal followed by a close paren, as with the final line in
(if foo
(bar quux baz)
42)
and there's *usually* nothing that can go wrong on such a line. When
there is it's usually an error in a *form* inside the literal:
(if foo
(bar quux baz)
[42 (count mumble) (.lastIndexOf frotz \q) 3 (19)])
;oops! -----------------------------------------^^
and that form will again have line metadata.
Eh. I suppose you could try extracting the namespace parts from
symbols embedded in the sexp. Ignore the ones that the macro knows
about, introspect on the rest to see which ones :use or :refer which
other ones, and whichever one is at the apex of the importation
pyramid is probably the namespace containing the macro invocation,
from which the filename can in turn be guessed. But that strikes me as
hackish and probably somewhat brittle.
> I would like to know what meta info does &form that get passed to
> your macro.. actually contain? I am able to only get the line
> number.. Is there a way to get the file name aswell?
The currently evaluating/compiling file (if it is a file and not the
REPL or some other instance of eval) is in the var *file*. The current
namespace is in the var *ns*.
Hm. *ns* is sometimes overridden (usually inside a call to "eval"
though) but *file* is probably pretty reliable and I did not know
about it, and it will directly give Sunil the file name he wants.
Thanks.