In PHP it is always a bother to "hide" the inner scripts so they are not accessible directly by the browser, because there are no effective way of telling PHP that these particular scripts should only be run by including other scripts, except via some url rewrite-fu. So we'll be one-upping PHP ;)
The idea is simple - if the script comes into a procedure that requires parameters at the top level of the request handler, then it should run
notfound.shp
instead.Hence we need to be able to tell the two types of procedures apart:
(define (thunk? p)
(and (procedure? p)
(let ((a (procedure-arity p)))
(cond ((arity-at-least? a)
(= (arity-at-least-value a) 0))
((number? a) (= a 0))
((list? a) (member 0 a))))))
Now we can fix
shp-handler
to check for the procedure's arity:
(define-struct shp-handler (path default not-found required)
#:property prop:procedure
(lambda ($struct request)
;; evaluate if
(parameterize (($pathinfo ($pathinfo))
($request request)
($server $struct))
(eval-script-if-changed! (shp-handler-required ($server)))
(let ((proc (evaluate-terms
(file->values
(url->shp-path (request-uri request))))))
(make-response (if (thunk? proc)
(proc)
(include! (shp-handler-not-found ($server)))))))))
Now the shared scripts are automatically hidden for you ;)
Shared Scripts vs Required Modules
It is worth noting that while both shared scripts and modules are "shared" resources, they play different roles. Each shared script represents only a single procedure, while the module can comprise many different procedures and other values. Most of the scripts should in fact be focused on generating representations, rather than doing any sort of substantial calculation. It is not that the shp script cannot handle complex functions, but PLT Scheme already provided one of the most advanced module systems available and there is no reason not to take advantage of it. SHP script's primary focus is on quick development cycle similar to PHP, so use them accordingly.
No comments:
Post a Comment