[plt-scheme] Using eval in modules
On Sat, 23 Jun 2007, Jean-Pierre Lozi wrote:
> This works because you are calling (eval-string-with-1 "abc") from
> outside the module - but it doesn't when the function is called from the
> inside the module. For instance :
>
> (module foo mzscheme
> (define (abc x)
> (display "foo")
> (newline))
>
> (define (eval-string-with-1 string)
> ((eval (string->symbol string)) 1))
>
> (eval-string-with-1 "abc")
>
> (provide eval-string-with-1
> abc))
>
> (require foo)
>
> Doesn't work. And that's what I need to do :/
Hello Jean-Pierre Lozi,
Question: do you really need the full power of eval? What are you really
trying to do?
If you're trying to expose a few functions to the outside world for
dynamic dispatch, then rather than eval, then would a simpler dispatch
table approach work for you?
Here's what it might look like:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module foo mzscheme
(require (lib "etc.ss"))
(define (abc x)
(display "foo")
(newline))
(define registered-handlers (hash-table 'equal
("abc" abc)))
(define (eval-string-with-1 string)
((hash-table-get registered-handlers string) 1)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
This requires no eval trickiness, and is much safer in terms of limiting
what kind of mischief the caller can do. If the user tries to eval
something that's not in the dispatch table, we can reliably catch that
kind of thing.
In contrast, the eval approach exposes the full power of the language,
including all the primitives, so in your original approach, stuff like:
(eval-string-with-1 "exit")
will kill the runtime.