Cold Fusion is NOT dead... ColdFusion is LIFE!

Over the last year or two there have been various reports that ColdFusion is dying, and that it's a forgotten technology. This has caused much furore in the CF Dev community, since a good many of them have built their careers on ColdFusion evangelism and ColdFusion development.

However, the recent TIOBE Rankings for April 2008 show that not only is ColdFusion not dead, but it's actually on the rise once again. While it still ranks below the likes of Ruby, Python, and C#, ColdFusion has surpassed Lua, ActionScript, and Groovy.

Of course, there are plenty who will argue the validity of using the TIOBE index, since it's based on Search Engine results, rather than actual market positions, or sales figures, but at very least, ColdFusion is doing a good job of generating posts about ColdFusion programming all over the internet.

CFINVOKE as a substitute for CreateObject

So, a while ago, faced with the fact that CreateObject and would be disabled on my main development environment by zealous security requirements, I began searching for a way to still allow myself to develop and work with OOP, even though the "Community Best Practice" methods for working with Objects weren't allowed in my dev environment. After a bit of experimentation and practice I came up with a pattern that worked remarkably well for me, and actually solved some of the other problems that I noted people were having with the "standard" invocation pattern.

My pattern is reliant on two things:

  • The CFC must have (or inherit) a public init function, which performs the duties of a traditional object "Constructor".
  • The init function must return a reference to the object, generally by ending with.

In the traditional paradigm, invoking an object is (almost) always performed in two steps. First , you get a fresh new object with either the CFOBJECT tag, or the CreateObject function. This object's psuedo-constructor (any code outside the CFFunction tags) has been executed, but any intializing values (dsn for a DAO, the MachII.framework.AppManager for a MachII plugin, etc..) have not yet been fed into the object, so it's really "half baked". It's not ready for general consumption. In order to make it ready for general consumption, you have to call an initializer on it. By convention, this function is called "init", and accepts any arguments that are necessary to make the object "ready for primetime".

A few people began to notice that this pattern broke your code up into multiple lines, which could be accidentally separated, resulting in the unitialized object references being released into the wilds of your program. One of these people came up with the bright idea of returning a reference to "this" from the init function. This allows your init function to be chained to the CreateObject call like so:

<cfset newObject = createObject("component","foo").init() />

This still is possible to mess up, but as Joel Spolsky once pointed out, one of the keys to making your code stable is making wrong code look wrong. If all of your CreateObject statements are immediately chained to an init function, then it's easy to track down errors where your instantiated-but-unitialized objects are released into the wild. If you see a CreateObject anywhere that isn't immediately followed an init, then you know at least one thing you need to fix.

This development inspired me. I knew that CFINVOKE could be used to in one operation, instantiate an object, and call a function on that object. The return value of that function call could be saved. What would happen if I ran a CFINVOKE on an init function that returned a reference to "this"? It turns out that the result is exactly the same as the CreateObject chaining that people were recommending before, but it didn't require access to the "forbidden" functionality.

Mozilla Prism

I took a look yesterday at Mozilla Prism. So far, i'm not particularly impressed, though I have to do a little more investigation into the webapp.js file and see what XPCOM stuff I can tap with it. As it stands, it seems like it's just a simple way to open up a chromeless browser window from the desktop instead of having to click a bookmark. Largely uninteresting, when compared to things like Google Gears and Adobe AIR.

Tonight i'm going to tap the Google Gears libraries a bit and see if there's anything in there that could be combined with Mozilla Prism to make something really cool.

Not again.

So, after the Christmas 2003 incident, you would think my family would have the good grace to avoid Heart Attacks on holidays. Unfortunately, we apparently forgot to tell my grandfather. We got news this morning that he is in the Hospital in Minneapolis after suffering a heart-attack at some point last night. My uncle Gerry and my grandmother are there now, finding out more details. My parents, who are visiting my sister and I in California are looking into cutting their trip short and heading home today to be at his side, and to be there for him.

Apparently Grandpa Ness has been feeling "not well" for the last two weeks now, but he's a stubborn old coot, and only sought out medical help on Tuesday or so of this week. I can only pray that he hasn't let this go too long, and that this is just something that he can recover from, and learn a lesson from. Regardless, I'm looking into flights to Minneapolis right now, and figuring out what I need to do to be there.

Google Groups

I've been fiddling around with Google Groups recently to communicate with my Roleplaying Game Group (Yes, i'm that kind of geek). I've been finding it very useful, and noticing one of the really nice hidden features: the "Page" editor. This page editor is basically a slimple CMS based on a standard "Rich Text Editor" sort of interface, but it's very powerful for my small group to be able to document things without going through the trouble of a full blown Word/OpenOffice/RTF document, or trying to link in a Google Docs Document.

Expanding beyond my current use, I can see it being very useful for a small development group to store API Docs, Design Docs, Requirements, etc. Yeah, there are more powerful tools available, but this one works really well, and has just the sort of versioning capabilities that are useful without being obtrusive.

"Well Formed" ColdFusion

I've run across a trend in ColdFusion code that's out there living in the wild web, to terminate "empty" tags with a />, like in XML. The best explaination I've heard for this behavior is to make ColdFusion code "well formed" XML. But what I don't see, is how this explaination holds water.

Maybe an XML programmer out there can point out, how is this:

<cfset var foo=ListFirst(bar,",") & listGetAt(bar,4,",")>

any more proper syntax than:

<cfset var foo=ListFirst(bar,",") & listGetAt(bar,4,",") />

Joining on Subqueries with SQL Server 2000+

Quite often I find myself wanting to get "the latest" result from a relational table. Normally this requires a subquery, which is slow. If I want more than one column from the relational table, I have to make multiple subqueries against a single table, which slows things down even more. However, recently, I discovered a new method: joining against a subquery.

Say I have a list of events, and each one has a status report against it. In my old scheme, I would have done something like this:

SELECT e.id, e.title, e.date,
( SELECT TOP 1 r.Author FROM reports WHERE r.eventID = e.ID ORDER BY Date desc ) as ReportAuthor
( SELECT TOP 1 r.Date FROM reports WHERE r.eventID = e.ID ORDER BY Date desc ) as ReportDate
( SELECT TOP 1 r.Status FROM reports WHERE r.eventID = e.ID ORDER BY Date desc ) as ReportStatus
FROM Events e

However, the new way that I've found of doing things is:

SELECT e.id, e.title, e.date, r.author as ReportAuthor, r.date as ReportDate, r.Status as reportStatus
FROM Events e
LEFT JOIN (
    SELECT eventID, ReportDate, Author, Status
    FROM Reports r1
    WHERE ReportDate = (
        SELECT TOP 1 ReportDate
        FROM Reports R2
        WHERE r1.eventID = R2.eventID
        ORDER BY reportDate desc
    )
    ORDER BY Date desc
) r ON r.eventID = e.ID
WHERE ....

The second form executes significantly faster in the tests that I've done.

AJAX with XML, without proper response headers.

One of my clients is dealing with an antiquated Lotus Notes 5.1 database for storing files, and I was asked to build an AJAX interface that would pull a list of files filtered by Category onto an HTML page. The Lotus Notes wizards were able to build an XML "view" of the files, which listed all of the files associated with a Document, however they weren't able to set the Content-Type of the response to "text/xml". This means that the standard XMLHttpRequest in both Internet Explorer and Gecko don't populate the "responseXML" property with the parsed XML document.

I also noted that the way in which the responseXML failed to be populated differed from browser to browser. In Internet Explorer 6.1, the responseXML.documentElement wasn't populated, but in Gecko, the responseXML wasn't populated.

So, I wrote a short snippet to handle responses which don't have the proper Content-Type header set:

function onXMLHttpLoad( objXMLHttp) {
    // First try to use the auto-parsed value
    var xml = objXMLHttp.responseXML;
    // The browser failed, but we think we're smarter
    if( !xml || !xml.documentElement ) {
        // Internet Explorer, use the Msxml COM object
        if( window.ActiveXObject ) {
            xml = new ActiveXObject( "Msxml2.DOMDocument" );
            xml.loadXML( objXMLHttp.responseText );
        } else if ( DOMParser ) { // Use the gecko builtin if it's available.
            xml = new DomParser().parseFromString(objXMLHttp.responseText, "text/xml" );
        }
    }
}

GNOME# 2 - The Revenge of the Documentation

So I'm launching into a project to teach myself Mono/C#/Gnome#, and I have happened back upon the main reason why I don't do development in those libraries and languages: The docs absolutely suck. Almost none of the tutorials I can find are written with the main standard development tool in mind, MonoDevelop, and so I fall back to the library documentation included in MonoDevelop.

The library documentation in MonoDevelop which includes such lovely pages as this.

Thanks guys. I mean, I can guess at what the strings app_id and app_version mean, but only after a few minutes of frustrating recompiles, and runtime errors I discover that the appname cannot have whitespace in it. This despite the clear violation of that rule in the Mono Handbook tutorial.

Of course, I realize these guys are Open Source developers, and as such, documentation is often the thing that suffers, but take a cue from the PHP and Perl folks. If you write good docs, they will come to your language. Then maybe you'll have developers capable of fixing the memory leaks.