today | current | recent | random ... categories | search ... who ... syndication

Wednesday, July 16 2003

Kake Pugh : How to Avoid Writing Code

The reason that Class::DBI and the Template Toolkit work so well together is simple. Template Toolkit templates can call methods on objects passed to them--so there's no need to explicitly pull every column out of the database before you process the template--and Class::DBI saves you the bother of writing methods to retrieve database columns. You're essentially going straight from the database to HTML with only a very small amount of Perl in the middle.

It should be noted that when the author says templates can call methods on objects passed to them she means both an object's accessors and it's mutators. This is not necessarily a problem if you are running your web application in a read-only situation and the web server, for example, doesn't have permissions to alter the contents of the database. But as soon as the program that processes templates has authority to muck with the database you had better have confidence in your TT kung-fu and/or the designers who are mucking with the templates. Not only could you do this :

[%"bar") %]

[% some_obj.update() %]

You could also do this :

[% FOREACH this_obj = some_obj.retrieve_all() %]

 [%"you lose, sucka") %]

[% END %]

(Note that retrieve_all is actually a package method but there's not much to prevent the object from calling it too.) All this with the both the EVAL_PERL and LOAD_PERL config flags explictly set to false. You can get around this, sort of, if your object doesn't have any circular relationships (e.g. A->has_a(B->has_many(A))) by adding a read_only method that sets a trigger to die before an object is updated or deleted. But there isn't really any way to cascade setting those triggers so there is always the possibility of mucking with the original object in a round-about fashion:

# this syntax may not be quite right

[% (foo.bars)[0].fooid.delete() %]

I've spent a little bit of time investigating (1, 2) how to make cascading readonly objects but it's still an ugly hack that requires mucking with private functions in Class::DBI. The proper thing to do would be to abstract all of this stuff into a CDBI::ReadOnly package but that might be a while in coming yet. Know you know. via paranoidfish

refers to


Tuesday, July 15 2003 ←  → Thursday, July 17 2003