Boil 'em,
mash 'em,
stick 'em in a stew!
This is one of those weird programming terms that I never bothered to learn, but discovered that I had already been using for a long time.
Polymorphism is an object-oriented programming design pattern. When you create an object, you have one or more methods (or functions) that each have a predefined purpose, each being a tidy, reusable black of code that you can use over and over again. The concept of polymorphism allows you to have one reusable block of code, i.e., a function, and have another reusable block of code that implements the same functionality of the other block verbatim, in addition to extending that functionality in some way.
When I researched the term, polymorphism, I found plenty of examples that do a piss poor job of putting polymorphism into the context of a real-world programming scenario. I will now hereby attempt to make a better example. In my PHP framework, I have implemented my own file system. This file system has the ability to pull file content from a variety of sources and display files and folders in a neat, tidy GUI. For example, some of the files are pulled from a pseudo-file system that exists in a MySQL database. Other files are pulled directly from the server's file system, but the implementation of this is designed to be dependent on what OS the application is hosted on. I did it that way so that I could take advantage of OS-specific functionality. Another place you might pull files from are places like FTP or SSH servers. In fact, who's to say that the objects in your GUI file viewer, must fit 100%, the adhoc definition of a file? Maybe you want to access a mail server and display messages and message attachments in an inbox as files. My framework's file system is designed so that file content can come from any source. Creating a new source is done by creating an OOP API template that includes methods that each provide "file" data in the same way. This method of development facilitates the creation of plugins.
There are actually a few different ways that you can approach this problem, PHP5 provides object templating via interfaces. You can define a collection of methods and the arguments those methods should take, and their visibility indicator (private, protected, public) in an interface, then every time you want to implement a new way of accessing file content, you create a new object that implements that interface. Then, your file manager can intelligently pick the right interface to pull, depending on the content that you're accessing.
If you were to implement a polymorphic programming pattern, that programming pattern would define default functionality that would always be used. For example, you can have a base class that defines certain things about file management that are shared amongst all of the different ways that you access files. Then, in each individual object that implements a new template for accessing files, that new object extends the base object defining default functionality. Then the methods in that object call the default functionality of the parent object, and add whatever other functionality that you might need that is specific to that particular way of accessing files. So, in other words, polymorphism is one programming design pattern that helps facilitate code reusability.
The following example is one way this might look, when actually put into practice:
In the example, the generic methods that you want all of your file interface implementations to share are defined in an abstract class. Then, you create an interface that defines the API of all the methods that your file interface implementation will implement, you do this so that PHP will check your implementation for you, and if you make an error and leave out a method that your application needs to properly support a new file interface, PHP will bail out with a fatal error. So interfaces are really a tool to assist with debugging, and don't really add anything useful to the application from the standpoint of functionality.
In the implementation, which is the beginnings for a Unix-specific method of accessing files, the polymorphic programming pattern is implemented by extending the abstract class, implementing the interface, and then overriding the getIcon() method defined in the abstract class. You implement the getIcon() method in the hFileUnix object, because you want to extend the default method of getting file icons with additional functionality that's useful for when you're dealing with the Unix file system. Another interface might be called hFileWindows, which would have its own getIcon() method, which would have functionality useful for getting file icons on a Windows platform. Setting aside whether or not this approach of getting file icons would really be practical in a file application, you can see how you're able to define some kind of default functionality, and then override or extend that functionality within child objects.
Within the getIcon() method, you can do some logic to see if the file is an image, and respond with a thumbnail of the image, instead of a file icon, which you might have some interface-specific code for retrieving. If the file isn't an image, you fallback on the default logic defined in the abstract class, which you are able to call upon using the parent keyword.
Of course, you may not want to enforce the implementation of the getIcon() method in the interface portion, since you could conceivably just use the default method, by default, and only implement a polymorphic pattern where the need arises. The methods you choose to enforce implementation of will be entirely dependent on how the rest of your application functions, the gist of the thing being, you only want to enforce implementations of methods that your application cannot live without, ensuring an API pattern is met thus allowing you create and leverage a highly-reusable code base that's easy to extend in new ways. This is all the more useful, since often times, after you've created an application you'll come up with all sorts of new and creative ways that application can be evolved.
In closing, there is actually more than one way to approach this particular design goal. You can also have an object that uses the method and property overloading feature supported by PHP5. Method and property overloading allow you to call on properties and methods that are not defined, whereas those calls are diverted to magic functions where you are able to make your application respond dynamically depending on what method or property was called. This can be useful for a lot of things, one application that I've used that programming pattern for extensively is lumping lots of methods together that have identical or almost identical argument lists, or all have other code that has to be executed. Essentially, overloading lets you take the logic of several, independently defined methods, and stuff all that logic into just one method, allowing you to eliminate redundant code. In terms of the polymorphic programming pattern, you can also include default functionality using overloading, as needed, and your individual interfaces are dynamically loaded and called from that object. This is the approach that I actually took in the implementation of my own file management application, whichever you use really comes down to a matter of personal taste.
Smashing! Brilliant!
Charles Miller points out how Apple's TV ads bear a striking resemblance to the plot of the class Roadrunner vs. Coyote cartoons.
It actually works! :-) Well done. Truly first class CSS support in Microsoft's browser. Renders complex CSS designs flawlessly out of the box. I, for one, am elated.
I haven't been able to dig into the scripting side much yet, but the rendering improvements are truly impressive. The half-finished product we saw with Beta 1 is definitely more polished and refined. The few regressions that I noticed seem to be fixed. And dare I say it, IE8 seems to be on par with Safari, Firefox, and Opera, at least in terms of CSS support. Of course the other browsers are still eons ahead with preliminary support for complex CSS 3 features, HTML 5, canvas, etc. And they've barely touched the scriping engine. At least they are working to plug memory leaks and make JScript processing faster.
The ability to switch between the IE7 and IE8 engines is also pretty cool, very seemless, and about as usable as a feature like that can get.
Over the course of the past year I've become a huge fan of Apple's Mac OS X on the server-side. Learning about and taking advantage of some cocoa programming fu, like CoreImage.
Of course, I'm primarily a PHP programmer, not that I couldn’t hack around in cocoa, I just haven't had much time to learn more about it.
Luckily, I don't necessarily have to learn cocoa to experiment with CoreImage on the server-side today. Thanks to Mark Liyanage's CoreImageTool shell application.
Mark's tool gives you the power to use CoreImage from the command line, and therefore from just about any scripting language that Mac OS X supports such as PHP, Perl, Python, and so on.
I've used this application to create a nifty thumbnail generator for my web-based Finder clone. Since it's powered by CoreImage, it supports a variety of image formats, allowing me to transform psd, ai, eps… and many others on the fly to web-supported image formats like png, jpg, or gif.
Writing the tool was surprisingly easy. To keep my PHP portable, I put in a check for Darwin, if it was present, I look for whether CoreImage Tool is installed. If it isn't, I fallback on PHP's GD extension, which unfortunately limits me to a much smaller pool of formats. In the future I should swap out GD support for ImageMagick.
Following is what the CoreImage portion looks like:
The preceding example is pretty simple, and yet fairly powerful as well. CoreImage can only resize an image via the specification of a scaling factor. In my example, I only allow the image to be scaled down, not scaled up, since this code is intended for creating smaller images, like thumbnails, from high-res source content.
To make things easier, I use the Darwin sips command to get the source image's dimensions in pixels, then I take the new thumbnail width and I divide that by the original width to get the scaling factor. For the destination, I have to specify an Apple Universal Type Identifier. I'm certain that part could be automated, rather than hard coded, like I've done. In the future I'll expand this script to automatically query that information. The UTI is Apple's own concept of a file type, and can be thought to be similar to mime types and extensions, but true to Apple style, is done in a much cleaner, more extensible way.
Mark mentions that his tool is written for Mac OS 10.4, Tiger, but I've been using it on 10.5 Leopard client and server without any problems.
That said, the preceding code is a small snippet of a much larger system that I designed that takes high quality source PSD files and converts and resizes them into web-accessible formats like PNG, JPG, and GIF, on the fly. And it's super fast to boot.
On Mac servers I love the advent of a neat feature called Time Machine. Time Machine does incremental backups without having to deal with 3rd-party software, or custom shell scripts like the one I'm about to show. Unfortunately, on the Linux side there's always some degree of elbow grease that's required. Which isn't to say you couldn't have Time Machine-like backups on Linux, you certainly can, it just takes a more concentrated technical effort, and you don't get the nifty GUI.
The following is a custom PHP shell script that I wrote for doing automated backups using the rsync command.
The backup script makes 31 uncompressed backups of the same content. I prefer uncompressed copies because that makes restoring from backup much easier. The script could easily be modified to archive and compress using the switches offered by rsync. And the script could also be modified to make more or less than 31 backups, I find a month a good round number for backups, combine this script with multiple external hard drives, and you can go back in time as much as you like.
This script backups to the same copy for 24 hours, after 24 hours, it will go on to the next, until it gets to 31, then it will start over at 1 again. I typically set this script to run on a cronjob on Linux or, on a Mac, you can link to it from an AppleScript, then set the Apple Script up as an event in iCal. Alternatively you can automate it via launchd as well if the iCal approach isn't feasible.
Using rsync for the backup processes makes the backup more efficient with time, since it only syncs changes since the last time a backup was done.
A crafty onlooker might see a lot of opportunity for adding command line arguments to this script that would let you passthrough the configurations automatically from the shell... I could have done that too, but the script suited my needs as it is written, so I didn't bother.
Et voilà! A PHP shell script for backups. Help yourself.
mod_rewrite is a very useful, and very complicated Apache module that lets you manipulate incoming requests. Uses for this module vary from redirecting content from one URL to another for the purpose of maintaing SEO and legacy URLs to simply making your URLs more readable and understandable, and not so weighed down with technical luggage, as it were.
mod_rewrite's documentation is pretty cryptic, but in that page lies most of what you need to know to use it. Though, albeit, you may have to read that page twenty or thirty times to truly understand how to use it.
One use I've discovered that lends itself well to mod_rewrite's magic, is redirecting traffic during a period of planned downtime. In the perfect world we'd never have to deal with downtime, but once in a while it just can't be avoided. The following technique allows you to look more professional while you are down, and gives you a chance to let your users know that the downtime is temporary.
There are a few ways that you could approach this, one method is to use a custom 404 error document, but that method may not be so good, since your HTTP server automatically sets the 404 response code when serving that document, and that can be bad for SEO. Instead, you want content to appear to exist, but you want all incoming requests to be routed to your downtime message.
The Apache configuration required to do this is surprisingly simple:
The preceding configuration can go inside a Virtual Host container, or it can appear in the main httpd.conf configuration file in lieu of any virtual host configuration, which will cause all traffic for all virtual hosts to encounter your custom error message.
There are two rules in play here: The first looks to see if the request includes the file name for your logo, logo.gif, which is stored at /images/logo.gif which is the path from your DocumentRoot. Without this rule, you won't be able to include your logo in the downtime message, since the request for your logo would result in your downtime error message being displayed. The second rule translates every path that comes in, that doesn't end with "logo.gif" to /index.downtime.html, which again is the path from your DocumentRoot.
Two of the configurations have been commented out, which allow for the specification of an error log, and the error level for that log. The path that you specify for the log must exist, of Apache will fail to start with an error. For more information on the log and the log level, see the mod_rewrite documentation.
I set out yesterday on an enormous task, to improve the performance of my PHP framework, Hierophant. I've been working on Hierophant since early 2005. One area that I never put much focus into was in the area of download and page load performance. It was always on the todo list, but kept getting pushed back for one reason or another. So yesterday I set out to patch this gaping hole in my framework's functionality.
I began with the most obvious enhancement, supporting gzip for various dynamic HTML documents, CSS, and JavaScript. Gzip can reduce the download size of a document somewhere in the neighborhood of ~67% for most documents. For example, I took Base2's already compressed base2-dom-fp.js (original compressed with Dean Edwards's Packer) and took it from 47KB to 15KB. Stylesheets went from 10KB to 2KB.
In addition to gzip, I implemented aggressive caching, setting the expiration times of scripts, stylesheets, and most images to 10 years.
So, agressive caching and gziping should alleviate a hefty chunk of performance issues, right? It did, in fact, in IE6, IE7, and Safari. But not in Firefox. Firefox 2, and the latest Firefox 3 Beta 5 were slower with gzip turned on than with it disabled. Not just a little bit slower, a lot slower. It takes literally eons for Firefox to load up gzip'd content.
Safari and even, gasp, IE6 and IE7 run circles around Firefox with gzip'd content. On the other hand, disabling gzip in Firefox brought its performance back on par with Safari and IE, which is completely baffling to me.
Ultimately, I did the only thing I could have done and that was to disable gzip for Gecko-based user agents, and left it enabled for all else.
So word to the wise, if you're going to experiment with gzip, Firefox and its Gecko-based brethren may not be up to the task.
Going back to caching, how do you update content that is set to expire 10 years in the future? In my framework I opted to append the last modified time of the file to every path output to HTML. So, for a script you'd see a path that looks something like this:
/Library/base2/lib/base2-dom-fp.js?hFileLastModified=1207280248That causes the document to be stored indefinitely, per the client's settings until the path changes. When the timestamp changes, the file automatically updates on the client-side. And I'm taking the same approach for images. This method allows you to utilize external scripts and stylesheets to their full potential, and as a result makes browsing blazing fast. Combine with other various optimization techniques, and you can make your site even faster than fast!
As a side note, if you've never heard of Hierophant before, I'll be blogging about that more in the future.
A bit of an about-face in my thinking has taken place recently. A while back I wrote a blog post about how I think "em" units are worthless for their intended purpose, that is to say, scalable font design that can stretch or contract to accommodate changes to the font size.
I still think that em units are probably never going to see the kind of use that some standards advocates hope they will. That's just one cold, hard truth of the web... you can make the tool available, you can outline its benefits in no uncertain terms, but the majority of so-called developers and designers out there are either completely uninformed, don't care, or both. So I don't believe that the usability portion of the em unit will ever be realized.
But after some thought, I did have a change of heart about the em unit itself. You can do some very cool things with em units. One example would be animation. You could design a box so that it's dimensions are all em based, then with a little JavaScript you could animate its size doing nothing more than changing the font size of the containing element.
Don't get me wrong folks, I long for the days of resolution-independent, scalable design, vector graphics, and accessibility. I just don't think em units fulfill the usability role very well, since most developers won't use them. Now that all of the major browsers are implementing the zoom feature, I think that will make the em unit obsolete for that particular application. And yes, zoom isn't perfect, its clear that will need to be refined too. But the em unit is an incredibly useful feature, and I recant saying otherwise.
It's pretty buggy. Lots of stuff coded purely to standards and not to a particular browser isn't rendering correctly. All in all though, that's expected, this is not the final product, they're still hammering away on some pretty big things.
On the topic of CSS, I'm happy to see some big things from CSS2 that are finally being supported. The table display types, the box-sizing property, generated content. I'm disappointed that they still haven't done much with CSS3 though. Some things in CSS3 seem pretty trivial to me to support, like most CSS3 selectors, for example, or the :target pseudo-class. JavaScript libraries on the client-side have been supporting CSS3 selectors for ages in their various Selector API implementations.
On the JavaScript front, I'm pleased to see that IE8 will support the querySelector() and querySelectorAll() methods from the new W3C Selectors API draft specification. That makes Webkit and IE (of all browsers) the first native implementations. That's a prediction I made that I'm pleased to see fulfilled.
I'm puzzled about some baffling ommissions in the JavaScript arena as well though. Why don't we finally have W3C events? Where are things like DOMContentLoaded, forEach, etc. The IE team, at least, in my opinion, could deliver more here, and again, it seems pretty trivial to me for them to add support for most of these things. So why are the improvements so slim?
Perhaps we can hope that the IE team is not yet finished with their improvements, but IE team, if you're listening, please add support for as much of these trivial things as possible. I appreciate the big, complicated bug fixes, but, in my mind I see a lot of little things that you could easily add support for, but for whatever reason are not. I'm not going to make blanket statements like, why don't you support x specification entirely, nor am I going to spit in the face of what you've accomplished, I can see that what you do have is pretty significant, but try not to overlook the smaller things that make everybody's life easier, that you could probably get an intern to do on a Sunday afternoon.
Temperatures plummeted to new record lows in hell today on the recent news of an about-face to IE8's standards mode default. If you haven't been living under a rock, I'm talking about the recent news that IE8 will, in fact, by default, act like IE8.
If you still need IE7 compatibility in IE8, fret not, there is an out for you in the form of Microsoft's <meta> tag/HTTP header proposal.
Seriously though, this is no less than awesome. The amount of goodwill and thanks shown by the development community on the IE team blog is unprecedented.
I woke up this morning with a strange, unyielding desire to hug Microsoft. It looks like the web is finally going to move forward in a big way.
This makes me feel like the end of Return of the Jedi, when on Endor, Hans and his Ewok friends finally managed to bring down the Empire's shield generator so the Death Star and the Galactic Empire could be obliterated once and for all, and then it was, and a victorious inter-galactic celebration ensued! Showing my true nerd colours.