[racket] Calling eval from the web server

From: YC (yinso.chen at gmail.com)
Date: Thu Sep 30 06:05:26 EDT 2010

Steve -

Others will correct me if I have this wrong, but IIRC #:servlet-namespace is
for sharing the namespace with other servlet modules, not for defining the
namespace for eval.

It looks like by default the current-namespace is empty (maybe web-server
set it to racket/base but in repl it's empty), so parameterize or explicitly
pass in a well defined namespace appears to be the way to go.  The simplest
way I've found is using the module's namespace, since parameters and structs
will be instantiated again in another module so if you use them your code
will "mysteriously" fail if you don't use the "same" namespace (there are
other ways of achieving the same effect but more complicated).

To do so use define-namespace-anchor in the module, and then convert it into
a namespace via namespace-anchor->namespace.  You can then parameterize or
explicitly pass it into eval.

Also I would suggest you replace "FAIL" with (format "FAIL: ~a" (exn-message
f)) instead, so you can see the actual error that would aid debugging.  Your
eval contains an error as it needs a quote for the list (1 2 3).  Not sure
if your problem was due to this missing quote or not, as it could be just a
typo for the email, but having the actual error message will aid the
determination.

HTH.  Cheers,
yc

On Thu, Sep 30, 2010 at 1:40 AM, Steve Knight <stknig at gmail.com> wrote:

> Hello,
>
> I'm using Racket 5.0.1 (from emacs) and I'm having trouble
> understanding some behaviour I'm seeing in the web server.
>
> If I start a servlet and dispatch some URL to this function:
>
> (define (ev request)
>   `(div (h1 "Last = " ,(format "~A" (last '(1 2 3))))
>             (h1 "Last = " ,(format "~A"
>                                    (with-handlers ((exn:fail? (lambda
> (f) "FAIL")))
>                                      (eval '(#%top-interaction .
> (last (1 2 3)))))))))
>
> I get "Last = 3" and "Last = FAIL" as the result, and I think I
> understand why.   Looking at the code of the web-server I think it is
> because the web-server places each servlet in its own namespace and
> that namespace does not include racket/list.   Therefore I think what
> is happening is that the first 'last' is compiled (from #lang racket)
> and so is fine and the second 'last' is not and so relies on the
> current-namespace.   Now because of the namespace fandangling done to
> preserve servlet separation, current-namespace is made from
> 'make-base-namespace' and so does not include racket/list.   So far so
> good.
>
> I can make this work by changing the call to eval to pass a well-known
> namespace to 'eval' but that is a bit awkward (and feels a bit wrong).
>  It seems like the right thing to do is to use the
> #:servlet-namespace option in serve/servlet (i.e.
> "#:servlet-namespace '(racket/list)") but when I try it it has no
> obvious effect although looking at the web-server code it seems like
> it should.
>
> Can someone tell me what I'm doing wrong?!
>
> Steve
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100930/fd7f5243/attachment.html>

Posted on the users mailing list.