[racket] Question about resolution of variable-name conflicts in namespaces
BTW here's the technique I devised, in case it's useful to others.
; define the values you need for include-template
(define body-for-template "content")
(define template-name "template.html")
(define page-result
(parameterize ([current-namespace (make-base-empty-namespace)]
[current-directory source-dir] ; set this to
your template directory if you want to use relative names in
include-template
[current-output-port (open-output-nowhere)])
(namespace-require 'racket)
(eval '(require web-server/templates) (current-namespace)) ; repeat
as needed for other modules your template uses
(eval `(define body ',body-for-template) (current-namespace)) ;
repeat as needed to establish your template variables
(eval `(include-template #:command-char #\∂ ,template-name)
(current-namespace)))) ; I use ∂ as exp delimiter
; go on to do things with page-result ...
BTW thanks again to Jay McCarthy for adding the command-char option to
include-templates, which makes it possible to have compile-time expressions
and run-time expressions in the templates, and also avoid escaping @
symbols.
On Wed, May 15, 2013 at 8:43 AM, Matthew Butterick
<mb.list.acct at gmail.com>wrote:
> Probably more products should have an FHQ (Frequently Hopeless Questions)
> in addition to an FAQ.
>
> I'm making a web-page generator that uses include-template from
> web-server/templates. I need to set the template inputs & the template
> itself at runtime, and collect the output.
>
> I tried doing it with module and module* but I didn't see how to make the
> data go round-trip. A submodule with include-template could require the
> needed data from the enclosing module, but then the enclosing module can't
> require the submodule to get the result, so ... ? I could well be
> overlooking an obvious technique.
>
> My original solution was to write a new file and send it through the
> Racket executable as a system command. (This worked, slowly.)
>
> So that's how I ended up using eval. Which does work, now that I've
> retooled how I set up the namespace.
>
>
> On Tue, May 14, 2013 at 5:13 PM, Robby Findler <
> robby at eecs.northwestern.edu> wrote:
>
>> The short answer is that the top-level is hopeless, as Matthew has
>> discussed at some length here and elsewhere.
>>
>> If you really need to eval code, can you first put it into a module?
>>
>> Robby
>>
>>
>> On Tue, May 14, 2013 at 11:09 AM, Matthew Butterick <
>> mb.list.acct at gmail.com> wrote:
>>
>>> Suppose x-is-foo.rkt is this:
>>>
>>> (module x-is-foo racket
>>> (define x 'foo)
>>> (provide x))
>>>
>>> If you open another file and try this:
>>>
>>> (require "x-is-foo.rkt")
>>> (define x 'bar)
>>>
>>> You'lll get a "identifier already imported" error. OK, that much I
>>> understand.
>>>
>>> Here's the question. When you do this:
>>>
>>> (parameterize ([current-namespace (make-base-empty-namespace)])
>>> (namespace-require 'racket)
>>> (namespace-require "x-is-foo.rkt")
>>> (namespace-set-variable-value! 'x 'bar)
>>> (eval '(print x) (current-namespace)))
>>>
>>> This time, you get 'foo. Why 'foo? Why not another "identifier already
>>> imported" error?
>>>
>>> I assume I'm missing a subtlety of how the namespace environment is
>>> different. But according to the docs, both namespace-require and
>>> namespace-set-variable-value! affect the top-level environment of the
>>> namespace. So I don't see why the require is silently overriding the
>>> set-variable-value, rather than causing a conflict.
>>>
>>> It's not a sequencing issue, because if you swap the two lines:
>>>
>>> (parameterize ([current-namespace (make-base-empty-namespace)])
>>> (namespace-require 'racket)
>>> (namespace-set-variable-value! 'x 'bar)
>>> (namespace-require "x-is-foo.rkt")
>>> (eval '(print x) (current-namespace)))
>>>
>>> You still get 'foo.
>>>
>>> Only if you remove the require line:
>>>
>>> (parameterize ([current-namespace (make-base-empty-namespace)])
>>> (namespace-require 'racket)
>>> (namespace-set-variable-value! 'x 'bar)
>>> (eval '(print x) (current-namespace)))
>>>
>>> Do you get 'bar.
>>>
>>>
>>>
>>> ____________________
>>> Racket Users list:
>>> http://lists.racket-lang.org/users
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130515/d5af1604/attachment.html>