I recently grabbed Class::DBI (v0.96) off of CPAN to help me wire up some simple objects with lots of database attributes. Now, when roughing out objects in Perl, I typically find it quickest to declare a package in the file scope of my working code -- it's like having a runnable test for the package's code write there in fornt of you. Most of the time, that's just fine and dandy -- as the code matures or gets unwieldy, migrating it out into its own .pm module files is fine. But I noticed that with Class::DBI, all kinds of weirdness can ensue if you declare your packages outside of the .pm module file world. I'd seen goofiness with older version complaining about not finding 'db_Main' in the package and yaddada yada. This time around, I tried putting everything in the file scope i.e. so it looks like this:
#!/usr/bin/perl use Class::DBI; my @britons = Criminy->retrieve_all; map { print $_,$/ } @britons; package Criminy; use base 'CriminyDBI'; Criminy->table('criminy'); Criminy->columns(All => qw(id foo bar)); package CriminyDBI; use Class::DBI; use base 'Class::DBI'; # someday, I'll have a dog and name him Django Hendrix CriminyDBI->connection('dbi:mysql:test','django','hendrix');
But this totally fails...
Criminy can't SELECT FROM criminy : DBD::mysql::st execute failed: You have an error in your SQL syntax near 'FROM criminy ' at line 2 [for Statement "SELECT FROM criminy "] at /usr/lib/perl5/site_perl/5.8.0/DBIx/ContextualFetch.pm line 51. at ./criminy.pl line 5However if I put each of those packages in their own .pm module file, it's totally happy. I can't explain it (and I really don't want to, it just sucks). Try it out, here's the mysql schema:
CREATE TABLE criminy ( id int(11) NOT NULL auto_increment, foo varchar(32) default NULL, bar varchar(32) default NULL, PRIMARY KEY (id) ) TYPE=MyISAM; INSERT INTO criminy VALUES (1,'Led','Zeppelin'); INSERT INTO criminy VALUES (2,'Black','Sabbath'); INSERT INTO criminy VALUES (3,'Deep','Purple');Anyway, the short answer: don't take any shortcuts. Declare your packages in their own file and Class::DBI will glide along swimmingly. ( May 25 2004, 11:52:22 PM PDT ) Permalink
There are tons of books from all of the usual suspects (O'Reilly, Wiley, SAMS, etc) about how to program with PHP but leveraging its crude support for OOP and employing best practices around that is seems to be pretty thin in all of the literature I've reviewed. The discussion I've seen on the web about object oriented PHP have also seemed weak; the commenter's who snivel about how complex OOP with PHP is underscore how toyish the use of PHP seems to be in many projects.
Before sending mail or posting comments insulting me for not appreciating PHP's simplicity, make sure you tell your Perl programming friends as well. I've been an adherent to OO in Perl for a number of years (though admittedly fell out of practice while my work was J2EE based) -- my gripes about prevelant practices amongst Perl programmers would be similar the above critique of PHP. In Perl, if you have a big blob of data and you want to find out what the heck is in it, you pretty much have to rely on Data::Dumper or, in PHP, print_r and then pick-apart the output to suss the structure that was created. Perl's man pages have several entries about lists of lists and and a data structure cookbook and so forth but the value of defining objects that provide a structural representation of the data (and of course, semantics) are too often overlooked in real software projects. If the changes I'm currently working on implementing had been using an instance of a class, I'd be looking at the object interface and making changes to the method calls. Instead, I'm looking at a big tangle of opaque data structures.
I could go on and on about how must PHP literature closely binds business logic and UI logic and the hideous morass that that creates, but I guess I already griped about that sufficiently in my high level rant about J2EE versus PHP. <sigh>
The code base I'm currently working on has a long way to go before the business data is captured in clear class definitions and there's a greater level of transparency into the relationships of the things within the application, but we'll get there.
( May 16 2004, 09:46:10 AM PDT )
Permalink