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
As of Perl 5.8, there's a module in the standard library with a boat load of things you need to with a list from time to time. It was nice to stumble upon the List::Util class; it's got a method called shuffle that does the trick. Here's an example of getting a randomized list using shuffle:
use List::Util 'shuffle'; my @list = ('a'..'z'); my @shuffled = shuffle(@list); # @shuffled is randomized, @list is unchanged print "@shuffled\n";There are more useful methods like min, max and sum that should make dealing with aggregations of values much easier. ( Apr 30 2004, 11:45:45 PM PDT ) Permalink
There are a lot of funky things about Perl5. Paradoxically, sometimes these are beautiful things as well. But oftentimes, they're just funky. As I've said before "I suspect with Perl 6, I'll only hate it on Tuesdays". I could rag about the weak encapsulation and the lack of useful method signature support in Perl5. But since I've really come to love Java's use of interfaces to compose an object's capabilities and disallowed multiple inheritance, I was interested in reading about Perl6's roles. Yes, in Perl6 a class can have a bunch of different roles. Here's a little bit of Larry from Apocalypse 12:
Roles can encompass both interface and implementation of object relationships. A role without implementation degenerates to an interface. A role without interface degenerates to privately instantiated generics. But the typical role will provide both interface and at least a default implementation.A little later, in discussing how roles are kinda like second class classes but not really, we see some hypothetical code:
The universe is a big place. And it keeps getting bigger. I guess I'll wait for Damian Conway to chime in. If Larry Wall writes the bible; Damian has to write the talmud.If you want to parameterize the initial value of a role attribute, be sure to put a colon if you don't want the parameter to be considered part of the long name:
role Pet[IDholder $id: $tag] { has IDholder $.collar .= new($tag); } class Dog does Pet[Collar, DogLicense("fido")] {...} class Pigeon does Pet[LegBand, RacerId()] {...} my $dog = new Dog; my $pigeon = new Pigeon;
In which case the long names of the roles in question are
Pet[Collar]
andPet[LegBand]
. In which case all of these are true:$dog.does(Dog) $dog.does(Pet) $dog.does(Pet[Collar])
but this is false:
$dog.does(Pet[LegBand])
At first I started messing around with Debian's vt100 utility, dselect (which it turns out is just a cheesey wrapper around dpkg) hoping to find something of the same caliber of the FreeBSD's package manager. 90% of the time, the FreeBSD tool won't give you too many surprises, it JFW's. I was not so lucky with dselect, what a POS! If you misfire some selection keystrokes and then leave your dselect session, you'll never be able to just undo what was there -- you can item-by-item set flags to "hold" the current state of individual packages but there's no way to just say, "the current state of the packages is how it is, don't flag anything for installation, removal, holding or whatever."
In the end, I read the man pages for apt-get and apt-cache; between the two of them, it looks like everything you'd want as far as package management tasks are available. My next foible was realizing that an installation can have a mix of packages from stable and the amusingly named unstable streams of Debian's deliberate development branches. Geez, I just needed libperl5.8 so I could compile something that embedded perl but the requirement to go to a different branch wasn't readily apparent from the dpkg -l listing (i.e. it required poking around a little research to discover that unlike the rest of the stable goodies, perl-base was from unstable).
And while I'm bitchin about how braindead linux distro's can get, what's with having libraries and header files in separate packages? What's I recall being so righteous about FreeBSD's ports-n-packages was that when you installed, say, zlib, you got the libraries and the headers -- there should be no need to install zlib-dev or something just to get the header files! What, are we concerned about diskspace usage? Why not just install the ding dang headers with the base package??
I remember a few years ago celebrating the news that the Open Packages project was going to bring the ports-n-packages thing of beauty to Linux and hopefully do for Linux what it'd been done for the BSD's a long time ago: a consistent, reliable and yet flexible package management system. IMO, RPM, Debian packages and Solaris packages all fall short.
( Apr 12 2004, 09:03:53 PM PDT )
Permalink
The first one was a little bit about tricks with server side includes ("SSI's") and some of the crude things you can accomplish with them that, while falling short of a "real" programming language, are surprisingly powerful. The browser detection stuff is very old and yet still very pertinent today when folks want to determine on the server side which CSS style sheet to send the browser. The other HOWTO is some notes I'd had about messing with HTTP cookies.
So I performed some minor updates on these things and reposted them:
The SSI Mini-Tutorial | ||
The HTTP Cookie Mini-Tutorial |
It's definitely a case of the something old/something new/something barrowed/something blue... there's a lot of stuff in Perl6 to like and yet it seems like some of the opportunity to unclutter the language appears to have passed us by.
Oh, darn.
Anyway, my thoughts on the matter are captured here
( Mar 18 2004, 08:41:25 PM PST )
Permalink
Here's the deal:
The tutorial covered SOAP interoperability between implementations in Java (using Apache Axis) and Perl (using SOAP::Lite). Some components on the Perl side required writing a few little modules. Nothing CPAN-worthy but still I wanted to package the modules nicely so users of the code samples can get the Perl side running without a lot of hand-work.
I read the man page for h2xs, the perldoc for ExtUtils::MakeMaker, I grabbed ExtUtils::ModuleMaker off of the CPAN and checked out it's docs ...the latter seems like an improvement but my needs were, IMO, real simple and I just wanted an appropriately simple set of steps. In the end, I followed a procedure similar to the one described here, bascially bootstrapping the package with structure with h2xs and manually tweaking the file system layout into something nice. Makes me wish Perl had a well defined self contained packaging structure similar to Java's jars.
Of course, then I'd want ant implemented in Perl to handle the packaging! So it goes. At the end of the day, the tutorial is at last online.
( Mar 16 2004, 09:14:49 AM PST )
Permalink
I'd installed RH9 on a box for a specialized use (a reverse proxy server built on mod_perl 2.0). It's basic deployment requirement was simply that it'd sit in the server room on a rack (i.e. headless). Everything went fine on the system installation and the software that I setup thereafter. However, after I racked it and put a little startup script in /etc/rc.d/init.d for the mod_perl instance I'd deployed, I rebooted it in it's "production" mode i.e. without any input devices attached. Lo and behold, it hung with a message about the power management stuff, something like
apm: BIOS version 1.2 Flags 0x03 ...
[it just stops there ]
So I set out to recompile the kernel. Since I don't do these kinds of things regularly anymore, I had to poke around and read through the procedures. Just for posterity's sake, this is what I did:
I used use FreeBSD for everything I possibly could. It's been a few years since I've had to custom build kernels for BSD but I recall the process being super straight forward; the amount of dickering around with different configuration tools was nil -- just edit a kernel config file and go compile that suckah.
I miss that. Unfortunately, all of the work that I do with Java is not compatible with sticking with BSD; my work is tuxified. If fortune shines upon me, my work in the future will be on Mac OS X where: no kernel dickering should ever be needed, it's BSD and it's slick.
( Feb 27 2004, 11:29:15 AM PST )
Permalink