It's even worse than it appears.
Thursday June 11, 2020; 9:19 AM EDT
  • Continuing the example from the previous case study. The routine, pad, takes three parameters, a string or something that can be coerced to a string, a character to pad with, and the number of places to pad to. So pad (8, "0", 4) returns a string whose value is 0008. It's useful for neat tabular displays. #
  • In an app I'm working on, I call pad a lot. Then, while testing it in a new environment, I got an error message from the JavaScript runtime:#
    • TypeError: Cannot read property 'toString' of undefined.#
  • Looking at the stack, the error was in the first line of pad. #
    • var s = val.toString ();#
  • I conclude that val is undefined in one of the many calls. #
  • The question -- should I find the place I called it with undefined and add logic to not call pad in that case, or should I add the test in pad, and return something reasonable when val is undefined?#
  • Now we get to the point of this case study.#
  • Changing a core routine like pad is tricky. If you change its functionality, you potentially break code that calls it. If it's been around a while, who knows all the places it has been called. However in this case, that's not an issue, because any call that has undefined as the value of the first parameter is going to fail. So it's already broken, therefore you can't break it and therefore it's okay to fix it. 🚀#
  • Then the question is if it's desirable to fix it in pad, or in the place that calls it that causes the app to fail. For me that's a no-brainer. It would clutter up every call if we don't put it in the function. The whole point of factoring like this is to trade off a tiny bit of time for space and reduced complexity. Factoring is a good thing, and you should do it whenever it's responsible. Remember what Einstein said. Basically factoring is good, but don't do too much. #
  • I call this coding technique defensive driving. It's something you do in case the other driver (the caller) screws up. You want to prevent the accident. Most of the time it won't accomplish anything, but when it does, it saves you from a crash. One less thing to worry about.#
  • So here's the new version of pad, with the defensive driving code added:#
    • function pad (val, withchar, ctplaces) {#
      • var s = (val === undefined) ? "" : val.toString ();#
      • while (s.length < ctplaces) {#
        • s = withchar + s;#
        • }#
      • return (s);#
      • }#
  • It makes pad a little more complicated -- a fact of life. Production code is rarely as simple as demo code because it has to deal with all the crap that gets thrown at it. Defensive driving is how you deal with that, the same as in driving a car or riding a bike in traffic. You never know what the other idiot is going to do. 😄#

© 1994-2020 Dave Winer.

Last update: Thursday June 11, 2020; 9:51 AM EDT.

You know those obnoxious sites that pop up dialogs when they think you're about to leave, asking you to subscribe to their email newsletter? Well that won't do for Scripting News readers who are a discerning lot, very loyal, but that wouldn't last long if I did rude stuff like that. So here I am at the bottom of the page quietly encouraging you to sign up for the nightly email. It's got everything from the previous day on Scripting, plus the contents of the linkblog and who knows what else we'll get in there. People really love it. I wish I had done it sooner. And every email has an unsub link so if you want to get out, you can, easily -- no questions asked, and no follow-ups. Go ahead and do it, you won't be sorry! :-)