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

Reply via email to