Sam-I-Am on Web Development

Sam Foster on the web and web-ish software developmen

Tuesday, January 15, 2008

A Parable

A man was asked to do some renovation on a house. He worked steadily at it for several weeks and finally called his client to come take a look around.

He said, "I was able to keep a lot of the original flooring. I got a good match for the wood and finish where I had to patch and extend the floor. I'm nearly done. I just need to pick up my offcuts and sweep up."

"Oh good" said the client. "So I'll arrange to start moving my family back in tomorrow. Sound OK?"

"Sure".

The main picked up some of the debris, and noticed an ugly dark spot under a piece of paper. As he scraped at it, it revealed itself to be the end of a protruding steel rod. By scraping away around it, the man was able to get pliers on it and wiggle it. As he did, something clicked below the floor and now several of the boards creaked as he walked on them. Creaking was one of the things he'd been called in to fix, so he pried up those board to take a look. There he saw that the steel rod was actually a pin that had been rigged to hold together some structural beams. It had been driven down to sit flush with the floor, but was now rusted away and very fragile. As he stared in disbelief, the beams began to drift apart, the house sagged and collapsed in a pile of rubble.

Moral: A job is done or not done, never nearly done.

Labels:

Wednesday, November 28, 2007

Simple Clocks with the Dojo Toolkit

Something I was playing with - this page shows a couple of javascript clock/countdown treatments. None are as whizzy as the dojox.gfx (vector graphics) clock you might have seen around, or your various dashboard widgets - but this is just dojo core + 6k (uncompressed) of code.

Labels: , , ,

Tuesday, November 27, 2007

string.replace with substitution by function

It may or may not be news to you that in Javascript you can do:
someString.replace(
  /\w+/g,
  function(match) {
    return "blah"
  }
);
Which in this case turns "the original string" into "blah blah blah". Your function is passed the match, and you return whatever you want. That's pretty handy, as you can run the match through transformations, or even use it to lookup or generate some entirely new value. You can also have side-effects from the match, which has interesting possibilities, not least of which is debugging: function(match) { console.log("I matched %s", match); return match); If you're like me, you might even think you could do something like this:
someString.replace(
  /<(\w+)[^>]*>)/g,
  function(tag) {
    var tagName = RegExp.$1;
    return tagName.toLowerCase(); // or whatever...
  }
);
.. but sadly you'd be wrong. At least as soon as you went to check in IE. It seems IE doesnt populate the properties from the match into the static RegExp object until after the whole replace is done. And your substitution function only gets passed the matched string, not the array of match + sub-matches you might be used to :( Still, there's plenty of mileage there. How about this:
  function format(str, obj) {
   var str = str.replace(/\$\{[^}]+\}/g, function(mstr) {
    var key = mstr.substring(2, mstr.length-1);
    return (typeof obj[key] == "undefined") ? "" : obj[key];
   });
   return str;
  }
.. which takes a string like "<h1>${firstname} ${lastname}</h1>", and an object like: { firstname: "Bob", lastname: "Smith" } to produce <h1>Bob Smith</h1>

Labels: ,