Dave's background includes a rural upbringing, a degree in zoology, work experience in software development, love of science fiction and fantasy, and a deep appreciation for video games.
-7 minutes-6 minutes-5 minutes-4 minutes
-3 minutes-2 minutes-1 minutecurrent
email:
icq: 5441050
aim: agkistradon
msnm: [on request]
yahoo: agkistradon
I'm not so much of a gambling man. When I go to a Casino, my only goal is to make sure that I get at least as much value in beer as I lose at the tables. In fact, this has worked out very well for me. Every now and then, though, a bet comes my way where I feel like I have special information that gives me better than average odds.

I also love ice cream. Mostly chocolate. Though I do have a soft spot for some other flavors, including sherbet (not sher-bert as many people seem to enjoy calling it). This isn't so important to know right now except to make clear that it's no secret around the workplace that I enjoy ice cream. Every now and then I walk over to the nearby grocery store and purchase a pint of ice cream, then eat it when I get back to work. Blessed with a fast metabolism, go figure.

"Restaurants aren't allowed to refill ketchup bottles, are they?"

"Of course they are," I said, nodding at the plain red bottle on our table.

"I wonder if that means ketchup doesn't require refrigeration."

What?! Surely he's got to be kidding. EVERYONE knows that ketchup requires refrigeration. "Sure it does."

"You want to bet?"

"What do you want to bet?"

J looked at me. I looked at him. Obviously he was gauging me to see if I thought I had inside information. And I did! I'd come up against this very question before in the past and had examined the ketchup bottle at home. It had indeed indicated that it required refrigeration. As did the soy sauce, syrup, teriaki, and A1. All those condiments that people routinely leave on the counter indicated on their respective labels that they should be refrigerated after opening.

Tilting his chin up, "a pint of ice cream."

"Deal."

"So, what are the exact terms of the bet?"

"How about we pick three brands of ketchup do best two of three?"

"Okay."

We both sat back at the lunch table, each smugly confident that we were about to win free ice cream. Our coworkers thought it was funny, and we finished lunch.

After lunch, J and I started off for the grocery store. Our workmates, incredulous that we were going through with the bet, laughed and bid us off.

We reached the store and easily made our way to the aisle of condiments where we were confronted by a few problems. First off, there were LOTS of kinds of ketchup. There were different flavors. There were different colors. There were "lite" versions. There were thick versions. Okay, maybe I made up that last one, but there were a bunch. We settled on three different brands of "plain" ketchup: Hunts, Heinz, and generic.

I picked up the generic bottle first and rapidly found exactly what I was looking for, "refrigerate after opening." Proudly, I demonstrated my find to J.

He started to lose confidence as he reached for the second bottle, but after thorough scrutiny, he declared that he couldn't find anything about refrigeration on it. I took the bottle and examined every bit of its surface, but indeed, there were no refrigeration instructions. Score: one me, one J.

While I was examining the second bottle, J had procured a third and was giving it a level of scrutiny unheard of in the ketchup world. A look of disappointment crossed his face as he handed me the bottle. It DID say that it required refrigeration. Unfortunately, as I turned the bottle over, I got a closer look at the main label. Organic. It fell outside the boundaries of our bet. I replaced the bottle and found the plain version of the same brand.

I looked.

And looked.

And started feeling a bit sheepish.

Nowhere on the bottle could I find anything about refrigeration. I handed the bottle to a hopeful J. He scoured the bottle, but found no label.

"I don't see it, but I didn't think any of them would." J attempted to let me out of the bet.

"Still, according to the terms of our bet, you won. Two out of three. What flavor ice cream do you want."

J picked, I bought. We walked back to work, him with ice cream, me without.

Sometimes I lose those bets.
I don't update here as much as I could, so it always surprises me to get any mail or anything as a result.

Miss Alyssa Megan emailed me recently with the request of doing a link exchange for the purposes of getting her a few more hits (why she might think I get a lot of hits is a mystery to me, but we'll ignore that for the time being). Apparently, it was recently her birthday (May 8). Happy birthday, Alyssa! Regardless, she'd like more visitors, so if you have a moment, pop on over to her site. She does some photography (saw some nice images on her site).

Other than that, I don't know anything about her. She's brave enough to ask for an unsolicited link, though, and I had a free moment.

Also, I'm sitting on a story about ketchup and ice cream. Will write it up eventually.
I've been playing World of Warcraft for about six months now. Just as with previous massively multiplayer games I've tried, I probably spend too much time doing it. It is a good time, though, and cheap entertainment. The past few months have been building up to the release of the first major expansion for the game. In fact, everyone thought the expansion would be released around Thanksgiving to coincide with the two-year anniversary of the original release. However, the release date got pushed back and back, and eventually settled on January 16.

As the day neared, I started checking locations that would have it. In doing so, I discovered that some stores would be opening at midnight to sell copies (score!). Mostly for kicks and giggles, I researched those locations. Best Buy had eight, total. Eight. In the United States. I was amazed. One in my city (which has six Best Buys without counting surrounding areas). Gamestop had lots of locations, including several in the city where I live. I didn't really research beyond that, because one of the Gamestops was about a mile from my house. Figuring that would be sufficient if I really did decide to buy it at midnight (which I wasn't planning on), I let it go.

January 15 rolled around. It was one of the coldest nights of the year here (a city where people just don't deal with the cold... at all). I was still waffling about buying a copy early, but over the course of the day events just kept unfolding to encourage me. It started when I discovered many of the people I play with were going to buy the game at midnight. Realizing that it would be an interesting opportunity to see the kinds of people that play the game, I started considering buying early. Weather services predicted cold, icy weather for the night and following day, and my workplace let us go early so we could beat the potentially severe weather. That coupled with the possibility of having to stay home the following day, unable to reach or find a store open and willing to sell the game, added more weight to the argument for buying early. When my wife came home and expressed that she just assumed I would be buying the game early, I made up my mind.

I played until around 11:30 PM (at which point, people in the eastern time zones were returning home and beginning to install their copies of the expansion), then decided to cruise over to the Gamestop. There were cars in the parking lot when I arrived and about 20-30 people milling around inside and out. I made my way in and milled around with the rest. Eventually I noticed a cashier checking people out and giving receipts, so I asked him, "how many copies do you have?" He said, "70." I said, "how many are preordered." That's when he said something that killed me.

"All of them."

They didn't have any left for walk-ins. In fact, they'd sold more preorders than they had copies, so if all the people who preordered had shown up, I'm sure there would have been a riot. At that point, I decided to just give up and head home, but as I pulled onto the feeder road toward my house, a little bell went off inside my head. I flipped the bitch and headed for the only other place I thought I had a chance to buy the expansion early: Best Buy. The one in my city that was one of the eight open was only 15 or 20 minutes away from my house at that time on a Monday night, so away I went.

When I pulled into the parking lot, I was surprised to find it relatively full (this is the biggest Best Buy I have ever seen anywhere, by the way). I parked well away from any other cars (that's just how I am), and started to walk. That's when I noticed the line leading from the entrance all the way to the edge of the building (probably 200 feet or so, easily 150-200 people or more). A fellow gamer teased me as we walked through the parking lot toward the end of the line, "don't these people have something better to do than stand in line for a video game at this time of night?" We laughed.

Then we reached the edge of the building.

The line stretched halfway to the back of the building! Probably another 100 or so people. We grinned, shrugged, and headed for the end of the line. As we walked, another guy joined us (turns out he went to college in the same state where I went, and at my school's major rival, no less). He suggested this Best Buy was supposed to have around 1500 copies (that's right, one thousand five hundred). Satisfied that we stood a good chance of getting a copy, we found the end of the line.

I spent the next hour or so inching forward with the line, chatting mostly with a 68 year-old lady who told me her stories of how she plays on two computers at the same time and has 100 characters (the limit for two accounts), including eight level 60s. There were all kinds of people in the line. People dressed in street clothes, people in suits. Men, women, black people, white people, Hispanic people, Asian people. There were some kids there, but most were probably in the 20-40 age range and more than a few people older than that (the lady I endured the line with speculated that she was probably the oldest player).

They let us into the store in groups of 20 and had plenty of copies to go around. The cashier who took my payment lamented that he'd showed up just to buy a copy for himself and got suckered into working. He also indicated they started with over a thousand copies of the game (which jived with the other fellow's story). When I left, I didn't go around the edge of the building, but the line still ran at least up to the edge. I'm guessing that there were something on the order of 500ish people there during the time I was waiting and buying my copy.

Even though it was 2 AM before I was able to get myself into bed, it was definitely worth the experience. It would have been worth it just to get the game, but getting the opportunity to observe some of my fellow players and talk to that woman with the 100 characters was just icing on the cake.
Working with the HTML DOM isn't always the easiest thing in the world. It is full of pitfalls and land mines and all manner of hazardous materials. One particularly sharp, pointy one that I've hit a couple of times now occurs any time I try to dynamically generate a styled table. One approach is to insert HTML directly into the document, while another is to build DOM nodes and append those to the document. Let's see what happens when we try to do each!

Consider the case that we want to put a table into the body of an HTML page, so we start off with something like the following.

<html>
<head>
<title>My test page</title>
<script>
<!--

function main()
{
}

//-->
</script>
<style>
.mytable
{
    background-color:red;
}
</style>
</head>
<body id="body" onload="main()"></body>
</html>


The page loads; the main function (empty right now) executes. No big deal. So let's focus on that main function for a minute. The goal here is to put a table into the body of this HTML document, but first let's just see what happens when we want to put in text. To make things easier, I went ahead and gave the body element an ID so that I could use getElementByID.

function main()
{
    var body_node = document.getElementByID("body");

    body_node.innerHTML = "This is a test.";
}


Okay, not so bad. We snagged the node object for the body of the HTML document and used the innerHTML property to set some content. Simple content like our text string is not a big deal, and this mechanism is perfectly acceptable for such an application, but what about our table?

function main()
{
    var body_node = document.getElementByID("body");

    body_node.innerHTML += '<table class="mytable">';
    body_node.innerHTML += "<tr><td>left</td><td>right</td></tr>";
    body_node.innerHTML += "</table>";
}


Not very interesting. A table with two cells, side-by-side. Depending on your browser (and we're shooting for cross-browser compatibility here so you've tried it on a couple, right?), you may or may not get any of your default styling on that table. Some browsers that hold a lot of market share that I shall not name here won't apply any style at all to that table. We did give it a CSS class name, so what now?

Let's make actual DOM elements and insert those!

function main()
{
    var body_node = document.getElementByID("body");

    // let's make the nodes we're interested in...
    var table_node = document.createElement("table");
    var tr_node = document.createElement("tr");
    var td_left_node = document.createElement("td");
    var td_right_node = document.createElement("td");

    // hmm, how about some text in those table cells?
    td_left_node.innerHTML = "left";
    td_right_node.innerHTML = "right";

    // time to glue things together
    table_node.appendChild(tr_node);
    tr_node.appendChild(td_left_node);
    tr_node.appendChild(td_right_node);

    body_node.appendChild(table_node);
}


Well, now isn't that snappy? We've got a table, a table row, and a couple of table cells. Seems to match the way we'd write the HTML, right? But we run it, and what? That's not right. At least not on all browsers. What is wrong? We review the code, but everything seems okay.

This is when I let you in on a little secret: not all DOMs were created equal. Seriously. Turns out there's another piece of DOM sugar that needs to be sprinkled in there to make everything work.

function main()
{
    var body_node = document.getElementByID("body");

    // let's make the nodes we're interested in, like before
    var table_node = document.createElement("table");
    var tr_node = document.createElement("tr");
    var td_left_node = document.createElement("td");
    var td_right_node = document.createElement("td");

    // one more to make things work
    var tbody_node = document.createElement("tbody");

    // hmm, how about some text in those table cells?
    td_left_node.innerHTML = "left";
    td_right_node.innerHTML = "right";

    // time to glue things together a little differently
    table_node.appendChild(tbody_node);
    tbody_node.appendChild(tr_node);
    tr_node.appendChild(td_left_node);
    tr_node.appendChild(td_right_node);

    body_node.appendChild(table_node);
}


Now everything is peachy! But what about style information? We could just use the setAttribute method of the table DOM node, and that would work in some browsers.

table_node.setAttribute("class", "mytable");


Unfortunately, it doesn't work accross the board. Fortunately for us, there is a way that does seem to work most of the time.

table_node.className = "mytable";


That className property seems to be relatively common, so that's the way I'd recommend going about it.

So, now we're able to build tables and style them on the fly. Of course, by the time I'd found all this stuff out, I'd invested way too many hours, but now that you can see it all at once, maybe you won't have to!

Happy DOMing, kiddos!
Time to leave a trail of breadcrumbs leading up to the three hours I spent yesterday working on my laptop (which runs Linux).

After I'd purchased my laptop and installed Linux, I discovered that there are no native Linux drivers for the Broadcom 802.11a/b/g network card that was included, so I dug up ndiswrapper (which allows me to load the driver written for Windows). No problem. Unfortunately, loading ndiswrapper would lock my computer during load from time to time, forcing me to reboot. Occassionally several attempts in a row would lock. Sometimes it wouldn't happen for a couple of weeks. Crazy weird.

Time passed and I upgraded my kernel to get support for some more things. The binary kernel distribution from Debian worked fine for me.

More time passed and I needed to enable some features of my kernel, so I downloaded the source distribution and made some modifications to the kernel. The new kernel worked just fine.

Later still I wanted to change some options in my kernel and rebuilt it again. This time, however, I got really weird messages during boot about ide-core dying. My laptop continued to work, so after two days of tinkering and unsuccessfully solving the problem, I gave up and decided to live with the problem.

Every time I changed the kernel, I had to rebuild ndiswrapper, no big deal.

Last night I finally got tired of ndiswrapper locking my computer during load (it did it twice in a row to me), so I went to find the latest version of ndiswrapper to see if that would solve the problem. Interestingly, there had been several versions of it released since the one I was using, so I was feeling pretty confident about it. When I tried to build it, though, it complained to me about the version of my C compiler. So, I downloaded the newest version of that I could and set my computer to use it. Still no joy. I had, at that point, four differet versions of the compiler installed, so I decided to go back a couple of versions so that I wasn't at the highest version, but still higher than the minimum requirement to build ndiswrapper. It built!

It would not load. Gave me some weird messages in the system logs. I looked around a bit and realized that it was complaining because I had built it with a different version of the compiler than I'd built my kernel. (Oops?) So, I decided to rebuild my kernel using the alternative compiler. Kernel built fine, modules built fine, everything installed fine. Reboot did not work fine. During reboot I got numerous messages telling me that the kernel was expecting modules built with the old version but was finding modules built with the new version.

An hour of tinkering later, I realized that I never updated a special part of Linux that is used during boot, the initrd, which is like a miniature copy of the OS that starts the boot process. I'd been using the same initrd that I'd downloaded with the original Debian kernal binaries. So, I spent a half hour figuring out how to create a new one and getting the appropriate tools to do so.

The new kernel made with the new compiler now worked.
The errors about ide-core (et al.) were gone.
The new ndiswrapper loaded.

I haven't figured out if it still locks or not, but at least the error messages are gone. Hopefully I don't make that mistake again.