[racket] Evaluating Racket source files from within another Racket source file

From: Matthew Butterick (mb.list.acct at gmail.com)
Date: Sat Apr 27 22:08:53 EDT 2013

OK, so the proposed solution failed once I tried to pass in the module name
as a variable. Even though enter! claims to take a module-path as an
argument, this will not work:

(define name "module.rkt")
(module-path? name) ; reports #t
(enter! name) ;  error: collection "name" not found

enter! is treating "name" as a module path instead of resolving it as a
defined term. What I can't tell is whether this is mandatory behavior for
enter!, or if it's a bug in the enter! macro. (I did look at enter.rkt, but
this week, it's over my head.)

Matthew Butterick

On Sat, Apr 27, 2013 at 6:16 PM, Matthew Butterick
<mb.list.acct at gmail.com>wrote:

> Aha, combining enter! with dynamic-require seems to do the trick:
> (define (route req)
>     (enter! "module.rkt")
>     (define foo (dynamic-require "module.rkt" 'foo))
>     (response/xexpr `(p ,(format "~a" foo))))
> Once this route is running in the web server, I can make changes to
> module.rkt, then click reload in the browser, and the changes will appear
> in the browser.
> If this is a terrible idea let me know, otherwise I'll consider this
> solved.
> On Sat, Apr 27, 2013 at 9:56 AM, Matthew Butterick <mb.list.acct at gmail.com
> > wrote:
>> I'm building a website using Scribble as the source format. As a
>> development tool, I've built a web server in Python that lets me view all
>> my Scribble source files and look at them in different states of
>> processing. To view the results of the Scribble files, the Python server
>> just sends the files to Racket via a system command (os.Popen) and reads
>> the result. This works but it's slow, because it  has to launch a new
>> Racket thread for every request.
>> I thought I could speed things up by rewriting the development web server
>> in Racket. But having tried a few approaches, I'm not sure how to duplicate
>> this functionality within a Racket web servlet:
>> *(require <modulename>) *
>> This only gets evaluated once, when the server is started. That doesn't
>> help, since the <filename> is going to be passed in as a parameter while
>> the server is running.
>> *(dynamic-require <** modulename **>) *
>> This gets evaluated only when invoked, and thus can take <modulename> as
>> a parameter, but then <filename> can't be reloaded (this is essential, as
>> the point of the system is to be able to edit the files and see the changes
>> in the web browser immediately)
>> *(enter! <modulename>)*
>> This reloads the file, but it's not clear how to get access to names
>> provided by <modulename>. (The documentation for enter! suggests that this
>> is not how it's meant to be used anyhow.)
>> Obviously, I could call a new instance of Racket as a system command, but
>> that wouldn't offer any advantage over the current approach.
>> I suppose what I'm looking for is an equivalent of the Python
>> reload(<modulename>) command.
>> Matthew Butterick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130427/fc39fa65/attachment.html>

Posted on the users mailing list.