ColdFusion Doesn't Need NULLs

I recently read Joe Rinehart's great blog on OO features in ColdFusion. His blog is, largely, a response to some discussions on the CFCDev list. In short, he feels that many of the OO features that some people are requesting be added to ColdFusion aren't a good idea.

The argument that I found the most interesting (on Joe's blog and the CFCDev list) was regarding NULLs.

The Problem

He defines the problem better than I can (reading his post first if you have time). Essentially, the problem is that having a returntype (say "numeric") for a method is helpful. With that help, however, comes a challenge. It isn't possible to return no value. With a returntype of "string", you could return an empty string. With a returntype such as "numeric", however, returning zero isn't the same. In fact, an empty string might not be the same as no value either.

Many (typed) languages (including SQL) handle this with a NULL. Basically, a NULL is an indication of no value at all.

The argument made by many is that NULL is needed so that we can take advantage of returntype and still return no value from a method.

My Proposal

I have run into this issue myself. Of course, adding a NULL to ColdFusion (or any typeless language) seems like a pretty major change.

As it happens, ColdFusion already has its own conception of this. A variable can be undefined (that is non-existent). A component with a returntype of "any" or "void" need not execute a cfreturn (and thereby return a value).

I would like an optional attribute (maybe "allowVoid"), which would allow a method with any other returntype to not execute a cfreturn. The attribute would have to default to false in order to maintain backward compatibility.

It is already possible to have the following code leave "foo" undefined (if myMethod doesn't execute a cfreturn). This change would only mean that myMethod could have a returntype of something other than "any" or "void" (if allowVoid is set to "true").

<cfset foo = comp.myMethod()>

This nice thing about this approach is that it plays nicely with how things work in ColdFusion already. It doesn't add a concept of NULL, which is foreign to ColdFusion. It does, however, add the ability to return nothing from a component without giving up the type-checking benefits of returntype.

I might also add that the problem already doesn't exist in cfargument as you can already set required="false" in cfargument.

Well, there you have it. If you have any thoughts on my proposal, I would love to hear them. If you have any thoughts on other OO features or anything else discussed in Joe's blog, please post them there to keep that discussion coherent.

Protect Yourself from Google Web Accelerator

Google has new tool called "Google Web Accelerator" out in beta that has the potential to cause quite a bit of trouble for web developers. Based on the information on the "Google Web Accelerator" help page, the tool is meant to speed up browsing for broadband users (as if our browsing isn't fast enough already).

The help page says that it does this in part by "Prefetching certain pages onto your computer in advance". This can effectively increase traffic on your site (due to the tool fetching pages that the user never reads) and mess up session tracking.

More significant, however, 37 Signals and other users report that this can cause the tool to follow "delete" links (among others) in an administration area (without respecting HTTP headers or JavaScript alerts). Note that I have not tried out Google's tool myself, for fear of messing up my own sites.

Google points to Mozilla Link Fetching as their model. This offers some hope because Mozilla's page says that they will only follow <link> tags not <a> tags. This, of course, is not what Google Web Accelerator appears to be doing currently. Given that Google's motto is "Don't Be Evil", hopefully they will correct the tool to work around these issues. In the meantime, we might be wise to protect ourselves.

Note that I don't believe this is a "panic issue". Few users have yet installed the tool and Google may make adjustments. Never-the-less, a little effort can help prevent potential problems.

How can we protect our sites?

The first thing to note is that Google Web Accelerator will not prefetch pages using SSL (https). If all of your administration sections use SSL, you have nothing to worry about.

If they don't, and if it isn't easy to make that change, you have a two other options (of which I am aware).

First, Damien McKenna has offered this bit of code which he says will block Google Web Accelerator:

<!--- block Mozilla Web Accelerator --->
<cfif structKeyExists(cgi, 'HTTP_X_MOZ')>
<cfif cgi.HTTP_X_MOZ EQ 'prefetch'>
<cfheader statuscode="403" statustext="Google Web Accelerator requests are forbidden." />
<cfabort />

</cfif>
</cfif>
Simply add that to the Application.cfm for your administration section (or any section/site for which you wish to block Google Web Accelerator).

Jochem van Dieten points out that the only reason that Google Web Accelerator can cause permanent changes on a web site (such a deleting information) is because so many of us aren't following the rules; namely RFC 2616 section 9.1.1 (he quotes the section below).
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe".
This is actually a very valid point. Permanent actions should be taken by clicking a button that spawns a POST action, not by clicking a link (and spawning a GET action). After all, users are used to links taking them to pages and buttons performing actions. It seems that this is the best fix because it is better for usability.

I plan to implement Damien's fix in the near future and change my applications to conform to RFC 2616 (and thereby hopefully improve usability as well) as time allows.


Read More:
http://www.houseoffusion.com/cf_lists/messages.cfm/forumid:4/threadid:40069

An Optimization Story

Despite talking about the benefits of CSS and optimization, my own web site has long been a paragon of bad code. Motivated by the CSS Reboot, I decided to finish the long-planned recode of my site done by May 1st.

The site was designed by Medulla Studio and launched in October of 2002. I put together the site using a patchwork of tables and styling.

The lightest drop-down menu I could find (by Milonic) was still a hefty 40K. An entire web page should weigh 34K or less (10 seconds on a 56K modem). So, no more drop-down menu. I plan to add a CSS drop-down menu later, but I have a deadline to meet.

I replaced some JavaScript with CSS styling (link hovers). Other (extraneous) JavaScript was just deleted altogether.

I re-cut up the top images so that things would be more as they seem. So, whereas one image included my logo and a gradient, I now have a transparent image above a gradient background image (had to help IE with PNG alpha transparency). The end result was faster-loading images and cleaner HTML.

For the central portion of the page, I again made things be what they seemed by replacing nested tables with clean CSS styling (working around an IE6 bug in floats in the process).

The footer was the biggest challenge. The design calls for the footer to be below all content and affixed to the bottom of the browser viewport. I tried popular techniques for footers, but I had little luck (trouble with Mac IE and sometimes with Opera as well).

It became easier upon realizing that I didn't need a "footer section", but just a bottom-aligned background image for the body (repeating on the x-axis only). This required a wrapper div for all of the content to leave space for the background image to show unobstructed.

Of course, Mac IE still wouldn't cooperate with my footer. No big worry, I just used the Holly Hack to hide the background image from Mac IE (it isn't in the new Mac OS anyway, so no worries).

Did my work payoff?

A check of the total weight of a sample page ("About Us") revealed following:

Total Page Weight:
old: 81.39K
new: 22.09K

HTML:
old: 12.69K
new: 3.89K

Number of Files:
old:27
new: 8

So, for about 25% of the load-time, all that I had to give up was a drop-down menu. I expect that I can add that back soon and still have far less load time than I had before. A little image optimization might balance that out completely.

Beyond the load time, my site is now more accessible. It also still functions without JavaScript (except that my logo will look funny on IE). It now looks good if images are turned off and is readable if styles are disabled.

Old:
http://orig.bryantwebconsulting.com/

New:
http://www.bryantwebconsulting.com/

Now I just need to add a drop-down menu, update the porfolio, rewrite the content...

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.