New Blog

November 28th, 2008

My old Nucleus blog was being overrun by spam comments, so I’ve switched over to a WordPress blog with Askimet spam filtering… We’ll see how well that works.

What Microsoft has to learn…

July 7th, 2008

This started as a response to Rob Gonda’s “Will Microsoft ever get it?” post, but I think there’s enough in here to actually build out it’s own post:

I tend to break computer users down along the “Neophile” vs “Neophobe” axis. About a third of the computer users out there will use any new technology as long as it’s new. These are the people who loved Vista, because it did new things that no OS before had done (or at least, not one that they had used). Most of them will upgrade to windows 7 just because it’s new, and they want to try it. Usually within this crowd there’s a certain tolerance to bugginess, because the “newness” outweighs the bugginess. In the most extreme case, these folks are Linux users, who run bleeding edge Gentoo releases and build packages of new software whenever they’re released. These are the folks who are subscribed to the Freshmeat and Sourceforge new software feeds, and install new software daily. I’m one of these folks mostly.

Then there are “Neophobes”, who hate new things simply because they’re new. These are the people who say “I’ve got my toolset, and it works, and it’ll take me weeks worth of time to learn something new, so why the hell would I want to upgrade to Vista?” These are the people who were running Windows 98 well into the 2003 timeframe. These people were angry enough that they were “forced” to upgrade to Windows XP, and this whole Vista thing just pushed them over the edge. A few picked up Macs, but then they’ll be back on the Windows platform in a few years when Mac OS 11 comes out and they get pissed about the fact that there’s now some weird desktop metaphor change that they aren’t used to and they’ll start reminiscing about good old windows, and how easy everything was there. There’s a fair number of these folks in IT too. Ironically, this crowd also hosts a lot of Linux users who are more than happy with their green phosphor command prompt thank you very much. There’s also a good amount of bug tolerance in this group because they would rather work with a software package that’s buggy, but they know how to work around the bugs, than learn something new.

Then there’s the middle ground. I call them the Pragmatists. They don’t care whether it’s new, or old, they just want something that works. There’s almost no bug tolerance in this group. These are the folks who coined the phrase, “Don’t use a Microsoft Product until the first Service Pack”. This group is actually a fairly small portion of the general IT population, since they tend to get beaten up a lot by the other two factions. However, this group makes up the vast majority of the general, non-IT population. Most of these people won’t bother even trying an application unless there’s an obvious need at hand for it. Likewise, they won’t bother with upgrading their OS until some outside circumstance forces it (They buy a new computer, with the new OS on it, they are forced to by their corporate IT policy, etc..) For most of these people, there’s no reason to switch to Macintosh, or Linux, because even the huge changes in Vista don’t significantly negatively impact them. Their Office stuff still works, though the toolbars took a bit of getting used to, and their email and web browsing work just fine, and that UAC stuff only affected them like 5 times when they were first setting up the computer, and then it hasn’t popped up since then.

The problem with Vista is that Microsoft got too caught up in the Neophile point of view. They made so many radical changes to the OS that it completely alienated all of the Neophobes to the point where even the people who despise change, and want to keep things as static as possible are chosing to change to Macintosh rather than learn the newness of Vista. And of course, whenever you make such massive changes to any large system, many bugs were introduced. This alienated a good chunk of the Pragmatists as well. What Windows 7 needs to do if it wants to succeed is move back towards the middle, to the Pragmatist point of view. New features are great, but don’t let them overshadow reliability, and for god’s sake don’t drop massive user paradigm changes into your most commonly used flagship products first without getting people used to them in other products. The ribbon bar in Office may be a good idea, in the long run. It may make office easier to use, but you’re terrifying about a third of your audience. It’s just not a good plan.

Cold Fusion is NOT dead… ColdFusion is LIFE!

April 28th, 2008

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

April 6th, 2008

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:

  1. The CFC must have (or inherit) a public init function, which performs the duties of a traditional object “Constructor”.
  2. 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

January 2nd, 2008

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.

November 23rd, 2007

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

March 22nd, 2007

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

November 30th, 2006

<minor rant>

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,”,”) />

</minor rant>

Joining on Subqueries with SQL Server 2000+

November 27th, 2006

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.

October 20th, 2006

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” );
}
}
}