If it quacks like a duck
Published 21 July 2008
Hi! You've stumbled upon a blog post by a guy named Ryan. I'm not that guy anymore, but I've left his posts around because cool URIs don't change and to remind me how much I've learned and grown over time.
Ryan was a well-meaning but naïve and priviledged person. His views don't necessarily represent the views of anyone.
I felt a bit elitist after posting about my desire that job candidates should have a low-level understanding of JavaScript. Today a bug I caught reinforced that belief.
JavaScript and Ruby are dynamic or duck-typed languages, meaning that variable values are converted between types when your code requires, allowing you to do things like:
"2" * 2 == 4 // true
Instead of having to manually convert between types. This allows some shortcuts for otherwise annoying code. For example, you never have to do
if (typeof foo == 'undefined' ||
foo === null ||
foo === false ||
foo === "0" ||
foo === '') { doSomething();}
You can just do
if (foo) { doSomething();}
In JavaScript you can also do some nifty type conversion:
"4" * 1 // 4
4 + "" // "4"
!! 4 // true
This can lead, however, to some odd bugs if you're not careful. I was receiving a boolean flag via JSON, which came across the wire as zero or one. In my application I had something that was essentially
if (flag) { makeTheMagicHappen();}
Unfortunately, flag
was coming in as a string, not an integer. I want flag
as a Boolean, but "0"
evaluates to true
, so my flag was coming up incorrectly. Worse, this was a pretty tough bug to spot. The solution, of course, is:
if (Boolean(Number(flag))) { makeTheMagicHappen();}
or
if (!! (flag * 1)) { makeTheMagicHappen();}
Worse, type coercion varies between languages. Ruby converts all values except nil
to true
.
Notes
- Actually, the solution is to change the bad data, but for complicated reasons outside of this post's scope, that's not possible. ↩