If you
(do
(binding [*ns* (find-ns 'foo)]
(eval bar)))
the evaluation of bar sees the global bindings in the namespace foo,
and can get at other global bindings and Java classes with
fully-qualified names, but cannot see the lexical environment around
the eval call. Even when called inside a let or a function body,
eval's contents only see what they would see if executed at the top
level of the source file for the namespace that is *current when eval
is called* (not necessarily the same file the eval itself is in).
Adding to this, you can work around it with
(defmacro eval-with-local-vars [vars sexp]
(let [quoted-vars (vec (map #(list 'quote %) vars))]
`(let [varvals# (vec (interleave ~quoted-vars ~vars))]
(eval (list 'clojure.core/let varvals# ~sexp)))))
user=> (let [a 1 b 2] (eval-with-local-vars [a b] '(+ a b)))
3
user=> (let [b 5 a 'b] (eval-with-local-vars [b a] a))
5
Note that the vars have to be in the correct order in the vector:
user=> (let [b 5 a 'b] (eval-with-local-vars [a b] a))
#<CompilerException java.lang.Exception: Unable to resolve symbol: b
in this context (NO_SOURCE_FILE:161)>
user=> (let [a 1 b 2] (map #(eval-with-local-vars [a b] %) ['(+ a b) '(* a b)]))
(3 2)
--
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
Yeah, nifty. I didn't know about &env when I wrote eval-with-local-vars. :)