Monthly Archive for August, 2006

Mollio

I've used Mollio on two projects now, and I have to say I'm really impressed.  The guys down at Daemon have done a great service to web developers at large by releasing Mollio as they have.  I can't say I particularly care for the red/black theme, but it's consistent, attractive, and unless you've got branding considerations, is perfectly acceptable.

It's also really easy to work with, as it's pretty unobtrusive in your markup.  Sure, there's some things you have to do a certain way (like the way you assemble forms or use THEAD), but nothing terribly bizarre.  I just took a little 15-page app that didn't have HTML tags or a stylesheet and Mollio-ized in about an hour, including some futzing with my layouts to not use (gasp!) tables.  In my defense, I assmbled the app in about 3 hours last night between midnight at 3am (and FB5, by the way, rules).

My next task with it will be to rebrand it a bit.  Starting with changing the color scheme and some of the L&F images, of course, and I'm hoping that'll be enough.  Their CSS is pretty well written, so I think I'll be able to get all I need with just that.  I'll also be extending the CSS (the form formatting stuff, in particular) to do some extra stuff (like per-field validation errors).  More details as that process progresses.

Anyway, if you haven't taken a look, highly recommended.  And all you BlogCFC guys out there, I'd bet Mollio would provide a 2-hour route to get away from the default look and feel with pretty minimal fuss.  It's got decorated pod support built right in and everything.  And when you're done, open source it.  ;)

Get Firefox - Piss Off

After much griping about my Get Firefox banner, I've added a 'piss off' (read: opt-out) link to the banner that will set a cookie so you won't see it again for 30 days.  After that, it'll tell you you still need a better  browser, but you can, of course, opt out again, ad nauseam.

CSS and Get Firefox

Everyone knows that browser compatibility is the bane of web developers.  If it's not a CSS bug or some DOM incompatibility, it's a plugin version issue (what's that, you say?  I'm thinking of something that starts with 'F' and ends with 'lex'….).  So help people put their best foot forward with a neat little CSS trick.  Drop this HTML into your page, just before the closing body tag:

<div id="betterBrowser" title="get firefox">
Get a better browser.<br />
<a href="http://www.getfirefox.com/">
<img src="static/get_firefox.gif" alt="Get Firefox" /></a>
</div>

And then this CSS in your stylesheet:

#betterBrowser {
position: absolute;
top: 0px;
right: 0px;
margin: 5px;
padding: 5px;
border: 1px solid #999;
background-color: #eee;
text-align: center;
display: block;
}
#betterBrowser[title="get firefox"] {
display: none;
}

Last step is to download the get_firefox.gif file and save it in the appropriate place (updating the HTML as needed). 

Voila!  Any browser that doesn't support CSS attribute selectors (cough … IE … cough) gets a nice little prompt to get a better browser.  No user agent sniffing, just a direct check for broken implementation.

Note that I'm running a slightly tweaked (though equally functional) version on this blog, so don't copy the code from my source.

floatToFraction UDF

Someone on CF-Talk just asked about converting floating point numbers back to decimals.  Always one to enjoy a little abstract thought on a random topic during my lunch, I threw together a solution:

function floatToFraction(num, maxDenom) {
var denom = "";
var numer = "";
var intPart = fix(num);
var sigFigs = "";
if (num EQ intPart) {
return num;
}
num = num - intPart;
sigFigs = len(num) - 2;
for (denom = 2; denom LTE maxDenom; denom = denom + 1) {
for (numer = 1; numer LT denom; numer = numer + 1) {
if (round(numer / denom * (10 ^ sigFigs)) / (10 ^ sigFigs) EQ num) {
if (intPart NEQ 0) {
return intPart & " " & numer & "/" & denom;
} else {
return numer & "/" & denom;
}
}
}
}
return intPart + num;
}

It's not perfect (feed it 0.7, for example), but it's a good start.  The tricky case is catching the irrational fractions (which is the source of the above mentioned imperfection), but a little clever rounding and it's easily solved for the majority of cases.  The maxDenom argument is for controlling the granularity of the fractions returned.  If, for example, you don't want to get any finder than eighths, you can pass 8 in as the maxDenom value and anything that would require a denominator of larger than eight will simply be returned as the floating point number passed in (e.g. floatToFraction(0.9, 8) will return 0.9, while floatToFraction(0.9, 10) will return 9/10).

ColdFusion and Java

No, this is not "that" post.

Since my post a while back about the new features of Java 5 (or Java 2 1.5 5.0 SE, or whatever the hell it's called), Sean Corfield and I have had a couple IM discussions about languages, development environments, developer mindset, tool support, frameworks, and various other things.

We were talking this evening and he pointed me to his post about Web Services, ColdSpring, and Reactor that I'd missed while I was ill last week.  I made the comment that I'm doing much the same thing, except with Spring, Hibernate, JUnit, and SpringMVC (to his ColdSpring, Reactor, cfcUnit, and Model-Glue:Unity).  He responded by saying, and I quote, "except in evil java rather than wonderful coldfusion ;)".  As you can surmise, we have differing opinions on some things, though at least from me, great respect for the other's viewpoint.  ;)

I happen to very much like compile-time typechecking, though largely for the improved tooling it allows (though I do enjoy JavaScript very much). I like strong IDE support.  I don't mind a little extra complexity for some additional flexibility, especially if I can ignore the complexity up front.

Sean likes his SmallTalk.  Later in that same conversation, he said "I never really liked the over-intrusive Java IDEs".   He'd also said something about how evil the EJB3 spec's use of in-code annotations for persistence was, even though they're fully overridable via external configuration/mapping files.

What's utterly fascinating to me is that we both get the job done (and it's almost the same job!), but approch it with such different mindsets.  It's not that we were trained differently, there's just some innate difference in the way we approach a given problem.  Something to remember next time one of those "religious" debates comes up on some list or another.  Almost always at least one wrong answer, but very rarely a single right one.

Should have signed up for Psychology, not Computer Science, eh?

Debuggers?

Over at Damon Cooper's blog, he's soliciting comments on the ultimate CF IDE.  What surprised me was the number of requests for a CF debugger.  CF Studio had one, way back in the day, and apparently people still miss it.

On a similar note, I've been doing a lot of Java development in Eclipse of late, and there's a heavy bent towards debugging in the JDT platform as well.  For example, F11 will debug the last launched app, while CTRL-F11 will just run it normally.  Seems like it should be just the opposite.

I've also gotten into a pissing contest with a New Atlanta representtive about the merits of debugging.  Paraphrasing here, but one comment was along the lines of "if you don't use a debugger, you're not a fully skilled developer". 

I personally haven't used a debugger since my CS 330 class down in Arizona, when we HAD to in order to complete an assignment.  I can say, with complete honesty, that I haven't missed them at all.  How's that, you say?  It's simple:

Unit testing and log4j, with an emphasis on the former.

Many checks you do with a debugger can be written as a unit test, which not only allows you to let the computer do most of the work, but it also lets you save the tests to be rerun later as part of a regression test suite.  Needless to say, this is a huge asset, as it can prevent the reoccurence of bugs, while an ad hoc debugging session is ethereal.

Unit tests aren't suitable for all situations, however, such as when you need to do some ad hoc examination of execution in order to pinpoint a bug.  This is where log4j (or whatever other logging package) comes in.  By allowing you put logging messages directly in you code and leave them there, you obviate the need to maintain breakpoints for your debugger.  Further, by allowing different loggers and log levels, you can very finely tune the output you'll get from your logging statements, something that's rather hard to do with breakpoints in a debugger.

Unit testing is something that hasn't really reached the level of acceptance in the CF community it deserves.  A large part of that, I think, is because the tooling isn't stellar, which is directly attributable to CF being a hard language to build good a unit testing framework.  The runtime nature of CF, while one of it's strongest assets as a RAD language, is also a weakness in this case.

Fortunately, with the CFLOG and CFTRACE tags, you can get some of the benefits of structured logging.  Or, if you're not afraid of a little Java, it's a snap to leverage log4j directly in your CF applications.