[PEAK] Persistence styles, MDA, AOP, PyProtocols, and PEAK
Robert Brewer
fumanchu at amor.org
Wed Jul 7 11:31:01 EDT 2004
Phillip J. Eby wrote:
> What good does that do? Well, think about storage. Suppose
> you defined a
> generic function like this:
>
> def save_to(ob, db):
> ...
Is this to support saving an object to potentially multiple stores?
Otherwise, I can't see the reason to make this a generic function, as
opposed to a method of the db class. In other words, what does this buy
you over:
class MySQLManager(SQLManager):
def save(self, ob):
....
...or is it simply having a hammer in your hand? ;)
> And what if you could define implementations of this function
> for different
> combinations of object type and database type? Maybe something like:
>
> [when("isinstance(ob,Invoice) and isinstance(db,XMLDocument)")]
> def save_to(ob,db):
> # code to write out invoice as XML
>
> [when("isinstance(db,PickleFile)")]
> def save_to(ob,db):
> # code to write out arbitrary object as a pickle
>
> Doesn't this look a *lot* easier to you than writing DM classes?
hmmm... not for the PickleFile, at least. ;) I see the modularity being
a big issue; in what module or layer would the first code example be
placed? Invoice.py? XMLDocument.py? App/Model.py?
> Which means that if you don't need, say, the pickle use case,
> you could just not import that module, which means that
> branch of our "virtual if statement" simply wouldn't exist,
> thus consuming no excess memory or CPU time. So, they can be
> "write anywhere, run any time". Now that's what I call
> "modular separation of concerns". :)
I've always found object composition (via dynamic imports at config-read
time) to solve this quite well. I guess it depends again on where you
see your "save_to" function being defined and invoked.
> In addition to the functionality proof-of-concept, I've also got a
> proof-of-concept Python expression parser (that so far
> handles everything
> but list comprehensions and lambdas) for what's needed to
> implement the
> fancy 'when/before/after()' API. And there's a
> proof-of-concept for the
> "function decorator syntax" as well.
FWIW, I handle when/before/after using triggers within attribute
descriptors.
> Further, the in-CVS prototype dispatcher automatically
> recognizes common subexpressions between rules, so
> that e.g. 'target.isDrinkable()' will get called only *once*
> per call to the generic function, even if the expression
> appears in dozens of rules. Also, the prototype dispatcher
> automatically checks "more discriminating" tests first.
Nice bit of coding, that. :)
> I haven't narrowed these down 100%, but here's what I think
> so far. The query language is probably going to end up
> being Python, specifically list or generator comprehensions, e.g.:
>
> [(invoice,invoice.customer) for invoice in Invoices
> if status=="pastdue"]
>
> However, these will be specified as *strings*.
Cheater. ;) Show an example using a date which has been obtained from
the end-user.
"""[(invoice, invoice.customer) for invoice in Invoices
if status == %s and duedate > %s""" % (coerce(stat), coerce(due))
Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org
More information about the PEAK
mailing list