iPhone vs. Blackberry vs. None

I used to carry a cell phone, but I haven't for the past year.  I don't miss really miss it.  Being able to whip it out and call someone any time I wanted to is nice, but not being able to call someone any time I want to is nicer, I think.  In our hyperconnected world, we, as a society, have lost "alone" time.  Sure, we're more dependent on others than we ever have been before (at least outside our immediate families), but how much should have affect our life?  With cell phones, plans can change at any time, and everyone can be told about it instantly.  That's good if you get in a car wreck.  Is it good when you forget milk at the store and call your spouse so they can pick it up on the way home?  Maybe I'm just a non-control freak, but I say that's worse.  The world isn't going to end without milk; drink something else.  Sure, it might be inconvenient, but maybe it'll help you remember next time.

I feel the same way on my motorcycle: the visor goes down and the world goes away.  If I'm late and driving a car, I rush.  If I'm late on my bike, I just don't care.  If I have to go somewhere and I've got the car, I leave as late as possible and drive fast.  With my bike, I leave early so I can avoid taking a route with traffic and/or stoplights as much as possible.  I don't know what the difference is, because it's not a conscious decision; it was a distinction I noticed in retrospect after I'd been riding for a while.

With that prelude complete, I'm debating getting a phone again.  I would love a device with JME that I could install my own apps on, but with the modern age, a solid browser is just as useful (probably more so).  Being able to whip out a computer that's always on and do something online real quick is of great interest to me, because I find myself consciously skipping certain things I want to do because getting my laptop is to much of a pain.  But I'm not sure I'm willing to pay the price of carrying a phone, both the permanent availability and the actual physical device being in my pocket (or wherever) all the time.  The iPhone is really quite a massive piece of equipment, and I already know what it's like carrying one of those around (ahem!).  The Blackberries are a noticeably smaller, but with a much smaller screen (smaller factor and dedicated keyboard).

An interesting dilemma to be sure, and with a large helping of irony on the side considering my profession.

I Am A Guitar Hero

Simeon, fine purveyor of electronic distractions, got me hooked on Guitar Here III last month.  I went over to his house for a Saturday of Halo and then some Chang's for dinner.  But unfortunately, his network wasn't cooperating, so we bailed on Halo and started playing Guitar Hero.  I have to admit that I was pretty skeptical having seen it played by others, but oh how wrong I was.  Eight hours later, with four aching hands, we decided we better go eat so we'd be able to type come Monday.

Of course, on Sunday I went an got my own copy (for the Wii), shelved Zelda again, and started rocking.  Tonight, I finished Career mode on "medium" (having already done Easy), after getting at least four stars on every song.  Now on to "hard", though I fear I have some unlearning to do.  With medium, you can play a finger per button, but not so much with hard.  Medium also didn't present any riffs that strumming only in one direction was too slow to accomplish.  I did try a couple songs on medium with alternating strums, and I cannot for the life of me get the timing to be smooth.  Between that and having to shift my hand up and down the neck, hard should present more than enough challenge, at least until I start memorizing some of the songs, so I can use my eyes to aid some of the left hand acrobatics.

The Custom Tag Body-Scope

I was working with FlexChart a little this evening and ran into an interesting situation with a potentially very useful solution. I don't claim to be the first to think of it, but it's the first time I've used/seen it.

I added a date preparation tag a while back, but I thought it'd be nicer to have a UDF that you could use instead, when you're building a descriptor inline. What I realized is that for very little effort, you can easily scope variables (UDFs or otherwise) to the body of a custom tag. Here's how it works:

<cfif thisTag.executionMode EQ "start">
  <cfset injectedPrepChartDate = false />
  <cfif NOT structKeyExists(caller, "prepChartDate")>
    <cfif NOT structKeyExists(variables, "prepChartDate")>
      <cfinclude template="udf_prepchartdate.cfm" />
    </cfif>
    <cfset caller["prepChartDate"] = prepChartDate />
    <cfset injectedPrepChartDate = true />
  </cfif>
<cfelse> <!--- end --->
  <cfif injectedPrepChartDate>
    <cfset structDelete(caller, "prepChartDate") />
  </cfif>
</cfif>

First, in the start tag, I (conditionally) add a prepChartDate UDF to the caller scope, and set a variable for whether I did it or not. Then, in the end tag, I delete the UDF if I'd added it to the caller. The part that I've greyed out is only needed because I'm using a UDF; it's a simple don't-double-define-a-function check. In this case, I'm opting to only expose the UDF if it won't conflict with what is already there in the caller scope. It'd be just as reasonable to shadow the pre-existing variable and restore it after the body. This latter approach is basically how Fusebox implements DO parameters, if you've ever used them, though it's mechanism is both far more elaborate and far more flexible.

I've obviously removed everything else from the tag definition. If you want to see the full implementation of xmlchart.cfm (where I used it), you can see it in Subversion (look near the bottom), and/or see it in action on the demo.

My Blog, My Rules

Charlie Arehart send me an email the other day  about my Flex charting control and the way it's presented on the site (which is poorly).  I ended up writing a fairly long response that was a bit tangential, but unreasonably so.  The basic premise was that it's my site, and I don't like maintaining web sites, so I do it as little as possible.  For example, I'd never bothered to actually put an email address on my About page.

But that expands out to cover some other bases as well.  For example, I actually release a fair amount of code, and I have a enormous amount of non-released code that I could release.  But you'll notice that I don't have a single software product that I maintain.  Contrast this with Ray Camden.  I don't claim that I produce the quantity of code that he does, but he produces products, not just code.

Productizing a software product is a huge amount of work, and maintaining that product only adds more.  I have little to no interest in dedicating my personal time to that.  Even just prepping code to release it takes a lot of work, in my view.  If I'm excited about something, I want to share it and get other people excited about it too, just like anyone else.  But the ROI is minimal, since I'm not trying to build any sort of brand or create an income stream.  Which isn't to say I don't have personal brand, just I don't cultivate it the way a business(wo)?man or consultant would.

So I'm curious.  Do people use the software I release?  Comment if you do, and list what you use.  I'm just wondering, because the code is rarely polished, it's not formally versioned, rarely has standalone docs (and often very minimal inline docs), and there is no promise of backwards compatibility or long term support.   Is that a deterrent sufficient to turn away people who's problems my code might directly address?  Should it be?

I know I'm apt to discount software packages that aren't actively maintained, but I'm far less likely to discount something if it's source.  Sure, I like to have someone else do the work, but if I find something that addresses a need I have, I'm going to use it if at all possible.  I'm quite lazy that way.

Then there are the blog posts themselves.  I go very back-and-forth on blogging.  I enjoy writing, but the blog is a weird medium.  In one sense, you're writing to nobody, but you're also writing to the readership you're aware of.  But that's never your complete readership.  And unlike most other forms of communication, you have rather little feedback on a blog.  Sure, people comment, but what percentage?  Contrast that with a document you write for responding to an RFP, an email you write to someone, or even an IM conversation.

As such, I dislike writing posts that don't have a clear point (like this one).  It leaves me feeling like I'm not done yet, and that I wasted every reader's time.  But at the same time, any sort of pointed discourse leaves me this wondering how I did.  Did I get my point across?  Was I confusing?  Without a specific audience and direct feedback, those questions are very hard to answer.

So why do I write on my blog?  Usually to share something I'm excited (or frustrated) with.  Hoping that someone else will read it and be excited too.  But it's always technical, because I know that most of the readers are techies, and have this weird feeling like I have to appease my perceived audience or a Bad Thing will happen.   But I want more than that.  I want to have a conversation.  To yell.  To ramble on.  To share the love of something.  I want to turn comments off so I don't have to listen to people.  I want to force every reader to comment.  I want to start an interesting philosophical discussion that persists forever.

I've considered dedicating a period each day to writing.  About whatever.  But I know that would leave me less satisfied, because it'd become a chore, and I wouldn't end up writing about the stuff that really blows my skirt up (no, I don't typically wear a skirt – makes for cold … legs … on the motorcycle).

What's the solution?  Someone knows.  Tell me.  Please.

New FlexChart Demo

I've updated the FlexChart demo to include display of the descriptor XML that is loaded into the chart, as well as providing a way to edit the XML inline and load your modified XML into the chart client-side.  In addition to being far easier to experiment with, it also showcases the the client-side redrawing of the chart and gives a hit of how powerful the engine can be within a JS UI.

Doing it this way means I lost the demo of having the chart request a new descriptor from the server-side on it's own, but the client-side descriptor injection is a "neater" capability, I think.   I haven't posted an updated zip of the source (including the demo app), but it's available from Subversion at the URL listed at the bottom of the demo.

A Very Wonky Request/CFTHREAD Bug

Found some really interesting behaviour with CFTHREAD over the past couple days of testing.  Put this code into three browser tabs and run them concurrently (so you get three simultaneous requests which you can view the output of).  And ensure you have the CF Server Monitor open in a different window with monitoring enabled and the Active ColdFusion Threads report showing.

<cfoutput>
<cfapplication name="#createUUID()#" />
<cfset request.threadName = createUUID() />

<h1>Request: #timeFormat(now(), "HH:mm:ss")#</h1>
<cfflush />
<cfdump var="#cfthread#" label="cfthread is empty" />

<cfthread action="run"
  name="#request.threadName#">
  <cfthread action="sleep" duration="10000" />
</cfthread>

<cfdump var="#cfthread#" label="one thread running" />
<h1>Thread: #timeFormat(cfthread[request.threadName].startTime, "HH:mm:ss")#</h1>
<cfflush />

<cfif structKeyExists(url, "join")>
  <cfthread action="join" name="#request.threadName#" />
</cfif>

<h1>Complete: #timeFormat(now(), "HH:mm:ss")#</h1>
<cfdump var="#cfthread#" label="thread shows completed" />
</cfoutput>

What happens?  As expected, all three requests return immediately, each having spawned a thread.  The server monitor shows that the threads all go away after ten seconds.  Most importantly, all three requests started, launched their thread, and completed at the same time (+/- a few tens of milliseconds).

Now go to the first tab and add "?join" to the URL, which will trigger the joining of the thread back to the request thread.  Refresh all three tabs again.  This time, the tabs without the join command behave exactly the same, but the tab with the join waits for the thread to complete before returning, as evidenced by the "Completed" timestamp.  This is all correct behaviour, so lets get down to it.

Add "?join" to the second tab (so now two tabs will join), and refresh all three tabs a third time.  Notice that the second tab that joins doesn't even start until the first joining request completes.  The non-joining request completes immediately, as always, initiating at the same time as the first joining request.

I don't even know how to characterize this issue.  It's certainly a bug, but I'm not sure what.  Even more baffling, I can't even come up with a theoretical scenario that would cause these symptoms.  Anyone?

Clickable FlexCharts

I just updated FlexChart with a 'click' callback.  You can now specify the name of a JavaScript function to be invoked when a data point on the chart is clicked.  The function is passed the ID of the chart, the series label, and the x and y values for the point, in that order.  Check the demo (which just pops an alert) to see it in action.

What is this good for, you ask?  Everything that CFCHART's 'url' attribute was theoretically good for, except it's actually useful.  If you wan CFCHART's behaviour, just have your callback do a window.location.  For those of us that don't, you can use the parameters to AJAX in some related content to another section of the page, compute and inject a new descriptor do do "drill-down" within the same chart instance, or any number of other things.  Lots of possibilities.

CFTHREAD/Server Monitor Issue

I was working with CFTHREAD today, and found an interesting bug in ColdFusion.  I'd wager that it's within the monitoring stuff new in CF8, but I can't say that for sure.  Here's the problem:

Creating threads with CFTHREAD makes them appear in the server monitor, but they aren't removed from the server monitor when the terminate unless the monitoring/profiling options are enabled.

To put that another way, threads give the appearance of sticking around forever unless you launched them with the monitoring/profiling options enabled.  I have no idea why this is the case, but it is.  The inaccurate state persists across reloads of the monitor, so the bug is somewhere inside CF, not the Flex app.  Threads that are listed but are actually dead don't have a value in the "Java Thread Name" column, you can identify (and ignore) them in the datagrid view.  The chart view, however, stays polluted until you restart CF.

Me.

For most of the US, as is common knowledge, this weekend was Thanksgiving weekend.  For most of the "white collar" workforce, that means a four day weekend.  Which brings up an interesting question.  What color is my collar?  It certainly not a laborer, which seems to mean it's white by default, but that seems … weird.  Lawyers wear white collars.  Who knows.

So what did I do with my weekend?  I (along with Heather and the kids) went to my folks house on the coast, ate copiously, stayed up WAY too late writing code by choice, watched some football, came back home Saturday, and went to the zoo for a picnic on an appropriately sunny, albeit cold, Sunday.

Work has been very frustrating since starting at Mentor, and it's only gotten more so within the past few months.  Suffice to say, not having to think about anything work related for four days was a blessed relief.   I don't want to imply that I'm one of those people who dreads going to work every day.  In the general sense, I very much like my career, just the specifics of the past "while" have me to the point of dread.

What struck me this evening, as I was opening my laptop to check my email one last time, was that I didn't want to just check my email.  I wanted to go get a glass of water and spend until the early hours of tomorrow morning banging out some more code (and Flex-based code to boot!).  That was strangely reassuring to me, because it meant that I'm still doing the right thing for my job, it's just the specifics that suck.

Work is something that I've always tried to cleanly delineate from my personal life.  The lens was certainly focused spending last year working from home, but it existed before and has persisted since.  One aspect that certainly contributes is that Heather doesn't really understand software development beyond a superficial level (the "yeah, so I cast the foo char to the boo-leen [sic] array, and pop the kernel stack" level), so the triumphs and defeats at work are hard to bring home with any sort of depth.

My evenings are, ironically, usually spent on the computers working on "stuff", where stuff is any of myriad personal application I've built and use, some public, some not.   I dislike watching TV aside from a handful of shows, but Heather follows a number of series, so she's often watching those or at practice for the community choir she sings in.  A significant portion of the R&D work I do is off the clock.  Which I don't really mind, because I'm going to write the code whether it's paid for or not, but it seems a bit odd from the 25,000 foot view.

Before leaving AudienceCentral at the end of last year (amicably, I might add), I'd been pretty much heads-down on a complete rewrite of the company's software platform.  A significant undertaking, as you might imagine.  Aside from that project, most of the "demanding" coding that I've done since the turn of the century is of a personal nature.  And not even "on personal time to be released open source to the benefit of all", but totally personal.  I put "demanding" in quotes above, because I have two very specific definitions in mind:

  1.  requiring significant effort to …

end of story, at least for tonight.  Heather just came and kissed me, and it was wonderful……..

One More Reason to Love GMail

Google released a new version of the GMail UI a couple weeks ago.  Not a whole lot different on the surface, but it's noticeably snappier overall, and has a few little improvements throughout (mute from the actions menu, contact detail popups).

I had two main gripes: it doesn't work with the [unsupported] BetterGMail Firefox plugin and the space bar didn't scroll up/down the page anymore (presumably from different key listening stuff).  The UI upgrade is backwards compatible, so you can, at your discretion, flip-flop between the old and new versions.  I debated about continuing on the old version, but I'd only just picked up BetterGMail and so wouldn' t miss it that much, and I figured I could learn to use the scroll wheel like a "normal" person not concerned with shaving literally hundreds of milliseconds of their email reading experience.

I finally got around to complaining about the space bar issue either Friday or Saturday morning.  When I logged on today the space bar scrolled correctly.  This isn't the first time I've gotten rapid gratification for my complaints/suggestions, though it's been a while, mostly because they've fixed all the things that bothered me.  ;)  I'm certainly not going to take sole credit for prompting this patch (or any other), but it's nice to know that as well as producing an email application that is actually user friendly (don't get me started on Outlook which is required at the office), they listen.