For those of you who aren't watching my Flickr stream, please note that I've recently uploaded a bunch of sketches. I'm moderately proud of them.

I plan to put more up, as I do them.

A Javascript Hack (using prototype)

Javascript with Prototype is the next best thing to ruby.

Okay, okay, this is a hack and it's not readable, but I was still tickled when I got this to work:

$A($('newqueuerequest').getElementsByTagName('img')).findAll( function(img) { return (img.src.indexOf("icons/red-x.gif") > -1); }).inspect();

Translation: "Give me a list of all img tags that have a red-x."

(I'm using this to ensure all fields are validated in a form, because the validation is complex.)

Why I switched back to Prototype from YUI

While I love YUI's documentation, I just can't help but prefer this:

function checkExistingNamesRequest(name, value){ var div = 'checkExistingNames_'+name+'_container'; loading(div, "existing "+name+" names"); var myAjax = new Ajax.Updater( div, "./checkExistingNames.cgi", { parameters: $H({ name:name, value:value }).toQueryString() } ); }

To this:

var svrCheckExistingNames = "checkExistingNames.cgi"; var checkExistingNamesSuccess = function(o, n) { if(o.responseText !== undefined) { $('checkExistingNames_'+n+'_container').innerHTML = o.responseText; } } nameHandler = function(o) { checkExistingNamesSuccess(o,; } var clientTest = nameHandler.bind({name: 'client'}); var projectTest = nameHandler.bind({name: 'project'}); var collectionTest = nameHandler.bind({name: 'collection'}); var collrefTest = nameHandler.bind({name: 'collref'}); function checkExistingNamesRequest(n, v){ $('checkExistingNames_'+n+'_container').innerHTML = "Checking existing "+n+" names... <img src='../icons/loading.gif' border=1>"; var test = clientTest; if (n == 'project') test = projectTest; if (n == 'collection') test = collectionTest; if (n == 'collref') test = collrefTest; var request = YAHOO.util.Connect.asyncRequest('GET', svrCheckExistingNames+"?name="+n+"&value="+v, {success: test, failure: test}); }

Which do you think is more maintainable?

(Frickin' Blogger is not meant for code, is it?!?)


I'm sorry, but I just think people are meant to die. Similarly, I believe memory is meant to be volitile. That, I believe, is a contribution to why AI has not come to fruition. Our brains are filtering systems, and computers have not learned what to keep and what to throw away.

When your memory is perfect, you--as a person--are broken. A fascinating paradox.

Ruby (again)

Well, today... I did it.

I asked the Lead Programmer if we could put our foot down and say: "From here on out, we will write for windows in C#, and for the browser in Ruby."

I was surprised I asked... I had been telling myself to hold off on asking that for a few months... but I'm not good at keeping secrets and I'm impatient when it comes to asking questions: especially questions that improve my lifestyle. So... out it slipped.

I was also surprised at his reaction. I expected him to say "No, and shut up about Ruby already, freak!" But he started by saying "that would be cool", and then arguing on my behalf, saying that "we have more Ruby experience than ASP.NET". (ASP.NET is our current alternative, not counting ColdFusion, which... well... is fine for informational websites, but not for doing actual work. And even for informational websites, it's so much more painful than Rails.) He also pointed out the fact that ... well.. Ruby is free. So it's not like it's a risky investment in that respect.

He didn't want to make a decision, but suggested I "call a meeting" with all the programmers (at least the four core programmers), and argue my point.

I've told myself I would hold off on calling this meeting for a week or two.

We'll see how patient I am with that decision.

...Man, I am such a Kool-aid-drinker when it comes to Ruby. ...And Agile. ...And OO.

Does that make me a chump? (Thanks, Andy.)

Speaking of Agile, we had another pair-programming session (actually, trio-programming, yuk yuk) today. Our code is finally starting to "do stuff". It's a scanning program, and we have it building a list of all the items that need to be scanned (for a given order). That was cool. Today we added the functionality that, when you scan one of the items, it "checks" the item off of the list.

When the program worked, all three of us jumped out of our seats, hooting and hollering.

...Made me feel like a toddler who giggles when he hits the button and the catepillar sings an out-of-tune digital song.

We (programmers) have one of the best jobs on the planet.

Speaking of the scanning software, it's actually quite cool: it talks to a table with a list of barcode patterns (because we don't know the acutal number to be scanned, we only know kinda what it's supposed to look like): we read the patterns out of the DB, run through all the items on the order, and when one of the patterns match, we mark that item as "scanned" (which does all the appropriate work, including ticking off the checkbox in the display). The RegEx includes groups, so that a Strategy Pattern can tell the Barcode object what to do with the number it scans, including all kinds of study-specific work. So something like "^6([AP])(\d{5})$" returns two strings, the first of which tells us what kind of drug it is, and the second which bottle number it is. The initial '6' is just a flag to tell us we're scanning a bottle number: we don't need to remember it. ...That's just an example: the code is actually extremely extensible.

We're all rather proud of ourselves, so far. :)


I got paid (for the first time) to write Ruby today.

A co-worker and I set up a new publications database and used Rails to get up the scaffolding for the website.

Of course, the only real "code" I wrote was to display a list of authors related to a partiucular title. I don't have the code in front of me, but it was something like:

<% for author in @title.authors %>
<%= link_to author.fname+' '+author.lname, :action=>'author_show', :id=> %><%= ', ' unless author === @title.authors.last %>
<% end %>

I had to create the title_controller.rb's "author_show" method, which was something like:

def author_show
redirect_to(:controller=>'author', :action=>'show', :id=>params['id']);

...And aside from a "has_and_belongs_to_many" from titles to authors and vice-versa... that was all I had to write to get that functionality (of displaying all the authors for a title).

Of course, I'm a little disappointed that I had to put that "<%= ', ' unless author === @title.authors.last %>" in there. Really what I wanted was a ".join(', ')", but I couldn't get that to work: I'm not familiar enough with link_to and... well... with tying bits and pieces of ruby together.

Even still, the way it is is very readable. (Yeah... that's my excuse, and I'm sticking to it!)

The co-worker that I was helping was very impressed with the amount of ground we covered in the three hours we worked on it, anyway. ...Note that over half that time was wasted trying to connect to the SQL Server database... (Turns out there is not trick to it, just set the type to "sqlserver" and fill out the rest of the fields intuitively!)

On the down side, I was so wrapped up in the project that I totally forgot that I had a date with my wife for lunch--and I was away from my desk, so I didn't get her calls. ...So I'm in the doghouse, now. : | D'oh.

A Wasted Hour

I just wasted an hour looking at this HTML:

...I couldn't figure out why the first set wasn't working (click on the second radio button and the first is still selected), and the second one was.

Then I realized I was using "ID" instead of "NAME" as an attribute.


Weekend Update

Three things to report:

My son and I played three games this weekend. The first was one called Heroscape, and it was the most age-appropriate of the three (we played the "simple" version). I won, but just barely. The second was Dungeons and Dragons Miatures. ...The rules were a little too hard, but he did quite well. And I have to admit: he was faster than I was with the math! He kicked my butt. The third was Star Wars Miatures. He mauled me.

Anyway, this is newsworthy only because I've long felt guilt about not spending enough time "playing" with my son. This was a good start. I have to say I was impressed... he lost the first game very gracefully, he learned the rules fairly quickly, and he didn't do anything overtly "stupid", tactically speaking. He did get overly excited about the game, especially the last one, where he was really wiping the floor with me. ...but that's him: he can't sit still and can't stop talking. ; )

I had a medical "slip" this past week. Last week, the doctor upped my dosage of Levothyroxine from 100 micrograms to 125. ...I had been having these occasional episodes of lightheadedness and chest "weirdness", that I couldn't quite describe. After the dosage changed, I started having them all the time. (Well, okay, several times an hour.) I noticed that if I took my pulse while these were happening, my heart-rate was all screwy. So I looked up cardiac arhythmia on Wikipedia and, lo and behold, this is a symptom of hyperthyroidism.

But it didn't stop there. Since I work with a dozen pharmacists, I asked around about it. I also work with six people who either have a thyroid imbalance or their spouse does... and I learned that the way my doctor was giving me my medication was prone to heart palplitations: this is why people normally start at very low levels of thyroxine and titrate up to the levels they need.

Anyway, I called the doctor--we was out--but another doctor at the office told me to go back to 100 micrograms, and to make an appointment for when my regular doctor gets back. I did both. The heart palpitations are completely gone now (three days later). All is well again.

It looks like I really will be using ruby at work! On Thursday, I had a meeting with all the other programmers about a new web-project that the center will be doing, and I argued for heavy use of Ajax. I showed my own code as an example--they were all very impressed--and then I showed the programmer who will head the new project how I was accomplishing it with Cold Fusion. I went on to explain a lot of the leg-work I was doing in CF was built-in to Ruby on Rails, and he was totally sold. We will pilot Rails next week, doing some pair-programming.

Not only that, but the center's lead deveopler asked me to schedule some sessions with the other programmers to teach them Ruby (and Rails), so we can all add it to our arsenal.

(I don't know if I logged this or not, but we recently switched from Visual Basic to C#, and have started pair-programming in it: it's insanely fun. Ruby will only be an improvement.)

With RubyCLR coming to maturity, and Ruby in Steel another option, I can't think of any reason why we wouldn't use it. A lot.

The lead programmer and I have already been joking about using IronPython (their main site isn't up at the moment). I wouldn't mind that. ...Though I admit, I've got a bias for Ruby at the moment. ;)

Perl is beautiful, and I will always love it... but I have come to admore "real" OO programming, and while it's possible in Perl... it's hackish.

Perl 6, of course, will be a god-send. ...But I am not holding my breath.

Ruby is, IMO, currently the most ideal scripting language. Java's bulky, and C# is... well... Microsofty (but I do enjoy it). C++ still reigns supreme in terms of speed and capability... but I'm a high-level programmer. ...But, most importantly, Ruby is fun, and has an amazing community. And Rails is pretty slick. : )

Another MS Gripe

What the fuck is it with GRIDVIEWS?!?

...Honestly, when was the last time you visited a website or used an application that had a FUCKING GRIDVIEW?!?


SQL Server vs MySQL

MySql supports dates. Really.

MySql exports CSV (without needing a GUI).

MySQL is free.

MySQL has excellent documentation, also free.

MySQL is programmer-friendly. SQL Server is a GUI with some half-assed database code underneath it.


A Possibility

A co-worker just asked me to look at his database ERD--a butchered version of Northwest Pubs (one of Microsoft's example DBs), to handle VA publication references.

I thought, "whoa, he could have this up in running in a few hours with Rails." I've been trying to sell rails to this co-worker for over a year now, so when I told him my thought this morning, he was prepared for it: ruby wasn't a foreign concept to him anymore. His response was "that's what I wanted to hear!".

We're scheduling some pair-programming to give it a whack in the near future.

Another co-worker overheard the conversation. ...He then asked me what I thought about another web-application...

[writhes hands insidiously]

Mouse Over

What's the fsck'ing point of a mouseover image?

...I mean, I could understand if you have some complicated imagemap, where it's not entirely clear where one "button" ends and another begins... but you can't really use a mouseover image in those cases. (Not on an HTML page.) Mouseover images are used in well-segmented menus, where the user is plainly aware of which option their mouse is hanging over.

So what's the point of making that option "glow"?

Dog on the Loose


...We just had our first "escaped greyhound" experience. ...Since we live in a city, this is a scary thing.

Fortunately, Talulla wandered about a block before stumbling into a fenced yard, where I "grabbed" her (of course, that doesn't imply any running--running after a dog is dumb). I tried to lure her with dog treats, but she wasn't having it. En route, she chased one cat under a car (pissing off one neighbor), and attracted the attention of two or three other neighbors. On her "walk of shame" back to the house (after I had her on lead), she had a run-in with a pair of black-labs... fortunately the owners were there to quell the bigger of the two.

Eeesh. Quite an adrenaline rush, that. ...And now she's tasted freedom, as it were, and we'll have to be doubly vigilant.



This is an open invitation to all of my listeners to "play" exquisite corpse. (A friend of mine--who's reading this--introduced me to the concept many years ago, but I've never actually tried it!)

Here's my thought:

  • Pick a pen, one that you're comfortable with, that I can find in a store, and is dark enough to photograph well. Tell me what the pen is. (I'd like things to match.)
  • Buy a padded envelope, and some standard 3x5 index cards (blank on at least ONE side), if you don't have them.
  • Draw something unusual (using said pen) on one of the index cards, and make sure the illustration "bleeds" over at least one edge of the card.
  • For each edge you drew over, line up a blank index card against it. Continue all of the bleeding lines onto the next card, but just barely (so I can see where to begin my lines).
  • Number the back of each card. Keep a "map" of which number cards line up with which.
  • Keep the original card you drew on, and mail me the "edge" cards to me. Email me for my address, if you don't have it.
  • Upon receiving the cards, I'll do pretty much the same: I'll continue on the card(s) you sent, and bleed lines over onto at least one other card, number the new cards, and mail them to you.
I've really started to itch to draw more, lately... and thought this would be A) fun, B) good practice, and C) a way to "connect" with friends/family.

Code-writing euphoria

I have a CGI that wants to validate a series of fields using Ajax.

I'm currently testing out the YUI toolkit. ...To be honest, I prefer Prototype, but I do want the breadth of knowledge to use both (and, next, I'll pick up dojo).

Anyway, back to the fields: there are three of them: client, project, and collection. I need to test if any of these fields have already been used (meaning: what the user enters must be unique), and I'm using Ajax to test this.

At first, I had a rat's nest of code, with basically a callback, handler, and response function for each one of the three. This, of course, made my teeth itch.

I tried refactoring, but I ran into the ubiquitouos scope problem in JS: I needed a closure around my "name".

After wrestling with it for two hours, this is what I ended up with, and it works beautifully:

// Check the existing names (client, project, collection):
var svrCheckExistingNames = "checkExistingNames.cgi";

nameHandler = function(o) {

// Stolen from Prototype:
Function.prototype.bind = function(obj) {
var method = this,
temp = function() {
return method.apply(obj, arguments);
return temp;
var clientTest = nameHandler.bind({name: 'client'});
var projectTest = nameHandler.bind({name: 'project'});
var collectionTest = nameHandler.bind({name: 'collection'});

function checkExistingNamesRequest(n, v){
$('checkExistingNames_'+n+'_container').innerHTML = "Checking existing "+n+" names... <img src="../icons/loading.gif%27" border="1" />";
var test = clientTest;
if (n == 'project') test = projectTest;
if (n == 'collection') test = collectionTest;
var request = YAHOO.util.Connect.asyncRequest('GET', svrCheckExistingNames+"?name="+n+"&value="+v, {success: test, failure: test});
...Why is it such a PITA to post code on Blogger? ...There must be a trick I'm not getting. (I'm using blockquote tags for nesting here!)


Okay, so I need to shut up about Seth Godin, already.

But he linked to a list that I enjoyed and want to refactor:

  • Real security comes from improvement. I once said "you don't ride an economy, you build it", and this is what I meant by that, in a less universal way.
  • Everything is version .9. ...which is a neat way of saying "nothing is perfect, keep improving."
  • Flexibility and efficiency are rarely mutual. Godin's point was different: he suggests that flexibility is "better" than honing a process... but that's for a marketer, and I'm looking for more universal advice. As a programmer, sometimes I want an efficient algorithm, sometimes I want a flexible set of tools. Each has its place.
  • Bet on change, in social situations. opposed to mathematical. By the way, I hate the saying "eveything is math": bullshit.
  • Creation requires iteration and influence. ...a better version of an old quote I used a lot: "Man does not create, he re-arranges". Creativity is the result of small changes to something old, influenced by something different. Enough of those changes, and it becomes its own, new entity.
  • Success abhores compromise.
  • Appreciate what you can, and endure the rest. And that, ladies and gentlemen, is a code to live by.

Administrative Action

I was told to be careful of what I say about the gummit.

That's a fair comment. But I admit I'm not terribly worried, and for two reasons. First, what I said is "true" (in the sense that I strongly believe it), and I would welcome the chance to discuss it with superiors. ...In fact, I considered it before writing the message. ...At the same time, I know it would go nowhere. For someone to take my comment seriously, they would have to strongly believe it too, and take up "the crusade", as it were... and I don't see my superiors caring enough about that problem to bother. (Honestly, I doubt I would, either, in their position--too much risk for too little reward). The bottom line was that I wanted to rant about a situation that cannot change, given the current "mood" of the country.

Secondly--and I want to speak on this--the gov't doesn't generally take action against individuals: they would rather institute policy.

I mentioned earlier (if I recall) an article about the difference between legal rules and principles. A refresher, as I understand it: principles are descriptions of what is right and wrong: situations that should be avoided. "Avoiding car accidents" would be a principle, roughly. Rules are guidelines for achieving the principle. "You must use your turn signal 200 feet before your turn" is a rule.

What I have long hated (and never really found the words to express) is that Joe Average is only aware of rules. Americans have a love affair with rules. Our kids are shooting other kids, let's ban guns. Kids aren't taking school seriously, let's make them wear uniforms. Someone tried to blow up a plane with fluids, let's ban fluids. Someone spent an entire day looking at nudie pictures on flickr... let's block flickr from the company!

Of course all of these things are wrong; they are problems. And of course they need to be solved. But creating rules isn't the way to solve them. I would go so far as to say they are profoundly unfair to the majority of people who understand the principle.


I wish I didn't need to be so verbose. Somehow Seth Godin says things like this (well, not quite like this, but other important, meaningful things) in a succinct, almost zen-like way. I wish I had that ability!

I'll continue pondering that...

The Neverending Story

Flickr is blocked.

I feel like Atreyu in The Neverending Story. I work for the gov't, and they have pretty serious filters on what you can view from the web. Until recently, flickr wasn't blocked... this was handy, because one could, say, go grab some CC-b photos for use in documentation or what-not, to spice things up. ...Well, no longer.

But worse, it's now interrupting my RSS-reading. I subscribe to several flickr feeds... and now the photos don't show up (and if I try to view them in another window, of course, I get the full error message). This is seriously disruptive to my feed-reading! I would say that about 1/3rd of the posts I see are pictures. I spend about 10 seconds looking at each. The other 2/3rds of my feeds are programming: c#, ajax, ruby, patterns, refactoring... and Seth Godin, whom I consider "work-related" in the sense that he's semi-motivational. ; ) I consider it part of my job to stay on top of these things.

I thought engagement--involvement--at work was a good thing. The fact that most of the feeds I'm on are work-related indicates that I'm dedicated to my job.

But now I feel like it's not worthwhile to do RSS! Sure, there was the occasional post that I couldn't open from work before... but now it's a full third of my stuff. I can't just click through them, either--I want to see these photos (which is why I subscribed), so I would have to mark each of them "unread" every time.

I'm ranting.

The point is simple: employees should be encouraged to engage fully in work. This implies integrating their work life and their home life. Blocking websites inhibits this ability.

Of course I can hear the argument: "VA resources are for official use only; private use is a violation of blah blah blah."

Tighten the screws, big brother... the more you twist, the more we hate you.

Pisses me off.

Holy Flurking Schnitt

(Turn off your speakers before you watch it: stupid rock music.)

It's amazing what people will specialize in. I shudder to think that, someday, this kind of card-handling will be considered "weak".

While I'm posting, I'll admit that I've fallen into the pit of internet video-watching. : ) I can remember laughing at the very idea of it, some years ago, thinking that there was no way the internet would be fast enough for video to be a viable "everyday" media.

Interesting times ahead. ...And a little scary, too.

An Age-Old Roleplayer's Lament

Found this on a WotC page:

A famous baseball radio announcer once claimed that anyone who tuned into his show hated him and every word he said until he gave them the score. I think it’s a little like that in a way for D&D players. Each game session, players can seemingly resent every plot and subplot, they hate every NPC, until finally the sweet release of combat comes heralded in by those two wonderful words: Roll Initiative.
...This is one of the main reasons I dislike D&D.

Mind you, I'm a biug believer in the old writer's adage: start with important action. As true in RPGs as in writing. But the assumption that D&D is nothing but a combat system... that bugs me.

Of course, this comes down to the age old debate of Naritivist/Simulationist/Gamist theory. But the assumption that D&D must be Gamist all the time is what wrecks it for me.


Simple Question

I got sucked into reading a news article on Bush's speech yesterday. (Not worth linking to.) It makes me sick to my stomach, quite literally, to read these things, and yet I still do. [sigh]

I have one question. It's the same question I've been asking for quite some time now:

What does "win the war on terrorism" mean?

Bluish-white Collars

An interesting article at O'Reilly led me to consider the difference between white-collar and blue-collar work.

Taking a white-collar job is the default path for a "normal" person, one less concerned with self-improvement and more concerned with enjoying life. When I was growing up, and such were the decisions my peers and I had to make, I considered blue-collar a brutish, manual life devoid of intellectuality, and I wanted nothing to do with it. It was with much disdain that I took my first job, which was in construction... and I was very quick to abandon in for a nice, quiet retail job (a book store clerk). To me, white-collar work was "winning", blue-collar was "losing". I dreaded manual labor.

Today I think quite differently about blue-collar work, considering it admirable, creative, and engaging.

I work a white-collar job, and as I look around me now (and the same has been true at my other jobs), I see a rather typical distribution of intelligence, as I would label it.

I suppose that's one of the reasons I miss college life. Professors, in my experience, are the types of people who engage me, even challenge me. While I work with some very intelligent people right now, it's a different type of intelligence, one that I do not relate to as strongly.

I can 't quite put my finger on it...