[PLUG] lisp problem: switching packages on the fly
Carlos Konstanski
ckonstanski at pippiandcarlos.com
Wed Nov 8 02:44:37 UTC 2006
> As one of the few PLUG advocates of Lisp, I feel that question is
> directed at me, so I'll try to respond. I have never really learned
> how to make effective use of packages. I once asked someone who was
> much more expert than I and had been the CTO of a company using Common
> Lisp in a more industrial way than I ever have (although, admittedly,
> he was a scheme guy at heart) and he said that they didn't use
> packages. So, I didn't get much of a leg up on packages from that
> conversation. I guess my advice is to read more about packages (in
> the Hyperspec, CLtL2, etc) and also ask on a Common Lisp forum like
> comp.lang.lisp. And if you figure it out, let me know.
> --
> Russell Senior ``I have nine fingers; you have ten.''
> seniorr at aracnet.com
Let's just say that I had you in mind as a hopeful, Russell. You did
get me thinking that package manipulation was not necessarily the answer
for this problem. You were right. I guess the java programmer in me
was looking for a stack of nouns to throw at the problem, when a verb
was clearly needed.
Instead of trying to call the function directly, making it execute
within the :araneida-site package, and have it try to call back into the
place where I should have stayed all along, I do it the lisp way, which
is to fetch the function as data and run it in the context of the
:jewelry-site package. This way, the compiler does not try to compile
the function as a top-level form, since it is just data. Therefore, the
function can contain anything at all. Its contents only get evaluated
at the moment the function is actually called.
(defpackage #:jewelry-site
(:use #:cl
#:araneida-site))
(in-package #:jewelry-site)
;; The data that is used by the shared function, but defined
;; locally here, in this child package
(defparameter skin-config `(:color-canvas "#539083"
:color-background "white"
:color-dark "black"
:color-medium "#779193"
:color-light "#dddddd"
:color-white "white"
:color-alink "blue"
:color-vlink "maroon"
:color-error "red"
:color-highlight "yellow"
:font-family "verdana, tahoma, helvetica, arial, sans"
:font-size-default "14px"
:font-size-text "12px"
:font-size-tinytext "10px"
:border "white 0px solid")
"A list of all style values for the webapp.")
;; The code that calls the shared function, which itself uses the
;; data defined local to this package
(defun with-wrapping-html ( &rest body)
"The template for most pages in the website. Renders the banner,
banner buttons, left-hand menu, footer and javascript DHTML library."
`(html
(head
(title ,(get-webapp-title))
((style)
,@(araneida-site:stylesheet-body))) ;; The moment of truth!
((body)
...)))
;; ====== ;;
(defpackage #:araneida-site
(:export #:stylesheet-body)
(:use #:cl))
(in-package #:araneida-site)
;; The shared function that is not compiled until the moment it is
;; called. Therefore, it can contain references to symbols that
;; are nowhere to be seen in the context of this package, as long as
;; it always gets called from within a supportive context.
(defun stylesheet-body (webapp-package)
"Outputs the body of the stylesheet."
#'(lambda () ;; The part that turns this function into a bunch of data
`(,(concatenate 'string
"body {
background-color: " (getf skin-config :color-canvas) ";
color: " (getf skin-config :color-dark) ";
font-family: " (getf skin-config :font-family) ";
font-size: " (getf skin-config :font-size-default) ";
font-weight: normal;
scrollbar-arrow-color: " (getf skin-config :color-medium) ";
scrollbar-track-color: " (getf skin-config :color-medium) ";
scrollbar-highlight-color: " (getf skin-config :color-medium) ";
scrollbar-darkshadow-color: " (getf skin-config :color-medium) ";
scrollbar-shadow-color: " (getf skin-config :color-medium) ";
scrollbar-face-color: " (getf skin-config :color-white) ";
scrollbar-3dlight-color: " (getf skin-config :color-medium) ";
}"))))
Carlos Konstanski
More information about the PLUG
mailing list