It does, right? On Wednesday, December 19, 2012, Alan Shaw wrote:
> But returning the evaluation was a requirement... > > > On Wed, Dec 19, 2012 at 2:58 PM, Alan Shaw <noden...@gmail.com> wrote: > > No, there was no requirement that it be a macro. Thanks! > > -A > > > > On Wed, Dec 19, 2012 at 7:40 AM, Dave Ray <dave...@gmail.com> wrote: > > A function seems to work fine unless I don't understand your requirement: > > ; normal version that takes code forms and symbols > (defn eval-in > [code ns] > (let [old (-> *ns* str symbol)] > (try > (in-ns ns) > (eval code) > (finally > (in-ns old))))) > > ; sugary version that takes strings > (defn eval-strs [code-str ns-str] > (eval-in (read-string code-str) (symbol ns-str))) > > and now try it out: > > user=> (eval-strs "(def z 500)" "bar") > #'bar/z > user=> (in-ns 'bar) > #<Namespace bar> > bar=> z > 500 > > Making this bullet-proof and deciding whether it's actually a good > design is left as an exercise for the reader. > > Cheers, > > Dave > > On Tue, Dec 18, 2012 at 11:22 PM, Alan Shaw <noden...@gmail.com> wrote: > > As an aside, I'm curious about whether this could have been implemented > > without a macro. > > > > -A > > > > On Dec 18, 2012 11:06 PM, "Alan Shaw" <noden...@gmail.com> wrote: > >> > >> Thanks very much Juan, that's some good study material for me. > >> > >> -A > >> > >> On Dec 18, 2012 10:45 PM, "juan.facorro" <juan.faco...@gmail.com> > wrote: > >>> > >>> The macro sees it arguments as symbols and does not resolve to the > >>> corresponding var until evaluation, so the value for the local code > var in > >>> the macro is actually the symbol generator. > >>> > >>> The eval-in macro uses the read-string function to evaluate the code > you > >>> provide, this function expects a string but it's getting the symbol > >>> generator instead, since that's what the macro got as a first argument. > >>> > >>> Here's a modified version of the eval-in macro, that delays the > >>> evaluation of the call to read-string: > >>> > >>> (require '[clojure.pprint :as p]) > >>> > >>> (defmacro eval-in > >>> [code ns] > >>> `(do > >>> (in-ns '~(symbol ns)) > >>> (let [ret# (eval (read-string ~code))] ; This line was changed > >>> (in-ns '~(ns-name *ns*)) > >>> ret#))) > >>> > >>> (p/pprint (macroexpand '(eval-in generator "another-ns"))) > >>> > >>> Here's the output: > >>> > >>> (do > >>> (clojure.core/in-ns 'another-ns) > >>> (clojure.core/let > >>> [ret__1879__auto__ > >>> (clojure.core/eval (clojure.core/read-string generator))] ; The > >>> unquoting of code resulted in the symbol generator > >>> (clojure.core/in-ns 'test-eval) > >>> ret__1879__auto__)) > >>> > >>> If you want to use a var as an argument for the code, you could resolve > >>> the var before changing namespaces, delaying the read-string until the > forms > >>> evaluation: > >>> > >>> (ns another-ns) > >>> > >>> (defn X [w h] [w h]) > >>> ;--------------------------- > >>> (ns this-ns > >>> (:require [clojure.pprint :as p])) > >>> > >>> (defmacro eval-in > >>> [code ns] > >>> `(let [code# ~code] > >>> (in-ns '~(symbol ns)) > >>> (let [ret# (eval (read-string code#))] > >>> (in-ns '~(ns-name *ns*)) > >>> ret#))) > >>> > >>> (def generator "(X 300 300)") > > -- 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