Good, bad, or just weird? You decide...
I've been using several different ad-hoc methods, not all entirely
satisfactory, to determine various arbitrary paths (URL or filesystem)
that are needed within a Quixote app. The issue is probably
independent of Quixote as such, but the approach I'm using now might be
less appropriate in other contexts.
So okay, let's talk about a plain CGI run under Apache to be concrete.
That's the environment I do most of my development in, anyway - it's so
much more convenient than resetting a persistent server every time I
make a one-letter typo correction. :-) In one small app I threw
together in the last week or two, I needed paths
* to the app's package in the filesystem for os.path
* to the app's config file as well as static data files
* the URL prefix to the app (ever try to generate a redirect from code
invoked by a path that's been massaged by mod_rewrite? when it can
have arbitrary parameters & options in the URL past the selector that
identifies the object that handles page generation? not pretty)
* the URL prefix to use for the external style sheets, which isn't
generally the same as the app (static file optimizations are nice,
but having the web server just do it without involving Quixote for
no benefit is the best optimization, IMO)
Maybe others - that was the lot for the lab monitor app. Under the
influence of a recent discussion about the difficulty of figuring out
the original URL from the varying clues different modes of running
Quixote may provide, I decided that since it seemed likely that I was
going to have to do this sort of thing over and over again, then I was
going to find a resuable pattern for it. I found an answer that I like
from viewing Python modules (or packages) as namespaces...namespaces
that make a great implementation for a Singleton. (Surely I've seen
that idea go by before)
So say I'm working on an app named "maps". Somewhere out there in the
filesystem there are a couple of directories I need to access: the maps
package's root and the config files (and subdirectories with files,
etc.) And those URL prefixes. Okay, so maps.cgi looks sort of like
this:
#!/usr/bin/python2.2
path = '/home/maney/Projects/maps'
import os
os.path.insert(0, path)
import maps
maps.set_data_path(path + '/etc')
maps.set_base_path('/~maney/maps')
maps.set_css_path('/~maney/css')
....
There are a few places further on where some of these paths come up -
the config file, for one. Sure, it *could* live in the script
directory, but that seems klutzy at best. So later on there's an
expression
maps.data_path() + '/quixote.conf'
that uses the earlier setup to find the Quixote options for its setup.
Of course these things get used more often in the app's code. maps,
for instance, has a set of room layout files that are found by listing
the directory
maps.data_path() + '/rooms'
So the lazy programmer has no excuse to hardwire the two rooms he's
personally interested in into the code, and it has a fighting chance of
being useful in other contexts without too much pain. Some of us need
to put on those blinders, sometimes. :-)
The implementation is, of course, trivial stuff like
....
_base_path = None
def set_base_path(path):
global _base_path
_base_path = path
def base_path():
return _base_path
....
I find the naming of these is just perfect, with the package name as
the object and the access function as the method. Dumping them into a
"real" object would just make the naming more cumbersome in return for
sharing only a very little bit of very trivial code. Unless there's
some non-ugly trick I haven't considered yet...
Anyway, that's one small annoyance reduced to almost nothing that I
thought I'd share with you. What awful drawback am I overlooking? :-)
--
Although we may never know with complete certainty the identity
of the winner of this year's presidential election, the identity
of the loser is perfectly clear. It is the nation's confidence
in the judge as an impartial guardian of the law.
- Justice John Paul Stevens, from his dissenting opinion Dec 12, 2000