So, after the post on events PJE suggested I try using generic functions for
events. I'm still not sure that's where I want to start, since
there's some more conservative options out there to address this.
However, I have long meant to use his generic functions, as I think
they seem pretty neat.
Installation was easy; following what the PEAK homepage says, I ran:
easy_install -Zf http://peak.telecommunity.com/snapshots/ RuleDispatch
It was a little problematic, because PyDispatcher also implements a
dispatch package. I ended up just uninstalling that, though
there's probably a better way to do it.
My first test was an experiment in converting objects to a JSONable form (result here). This worked
very easily, and with no surprises. Of course, it's an easy problem.
But still, it's not a given that introducing a new tool to solve an
easy problem will give an easy result.
Using this, you can fiddle with the JSON representation of nearly any
object. For instance, lets say you get Binary objects (like from
a database BLOB column), and you want to turn them into
base64-encoded strings:
@jsonify.when('isinstance(obj, Binary)')
def jsonify_binary(obj):
return str(obj).encode('base64')
The only issue I have with the implementation is that it's hard to say
apply this rule only in this context, because jsonify() doesn't
have any argument that implies context. So if you wnat to change
the representation of an object, but only in the context of one controller
in your web app, then that doesn't fit into this system. Dynamically
scoped variables would probably address this case.
Anyway, in my second test I threw in a context argument parameter,
just for this kind of thing. Especially because in my second test I
wanted to allow something most other adaptation systems can't --
detailed tweaking of specific cases based on arbitrary rules that
don't have any overriding sense to them. These are exactly the
rules that make up good UI design, and my second test is for
generating forms from objects.
For the second test I added some (experimental) modules to FormEncode (new website, BTW): fields,
formgen,
and sqlformgen
(the SQLObject-specific form generation routines), and a test.
And while the result is by no means complete, and there's still parts
of the design I don't understand well, again the generic functions
didn't introduce any surprises. I suspect when I try different
combinators or some other tricky thing they will surprise me
eventually; but of all the parts of this (rather difficult) problem,
the generic functions seem the easiest.