Racket provides protect-out
to prevent module exports from being used with eval (or a deconstructed syntax object), unless the module has enough privileges (aka, has a strong enough code inspector). The docs also provide a good example for what it does:
> (module nest racket
(provide num-eggs (protect-out num-chicks))
(define num-eggs 2)
(define num-chicks 3))
> (define weak-inspector (make-inspector (current-code-inspector)))
> (define (weak-eval x)
(parameterize ([current-code-inspector weak-inspector])
(define weak-ns (make-base-namespace))
(namespace-attach-module (current-namespace)
''nest
weak-ns)
(parameterize ([current-namespace weak-ns])
(namespace-require ''nest)
(eval x))))
> (require 'nest)
> (list num-eggs num-chicks)
'(2 3)
> (weak-eval 'num-eggs)
2
> (weak-eval 'num-chicks)
?: access disallowed by code inspector to protected variable
from module: 'nest
at: num-chicks
That is, eval
had a powerful enough code inspector (because it was called in the same scope that required the module originally) and therefore was able to get the export. However, weak-eval
did not, because it got the same instance of the module, but with a weaker inspector to use for eval
ing.
My question is, when should we use protect-out
? Should it always be used (or at least whenever possible)? Or is there a specific work flow that protect-out
is designed for?