The semantics and differences in variable capture mechanisms for closures between various programming languages is a fascinating topic. One of my favorite examples is^H^Hwas Ruby’s scoping mechanism for blocks. The problem is acknowledged and eloquently explained on page 105 in the second edition of the pickaxe book. I am particularly amused by the proposed pragmatic solution; keep your code small so that it is easy to spot any potential problem, and use some form of Hungarian notation to put local variables and block parameters in a different lexical namespace. Fortunately, this issue is fundamentally fixed in Ruby 1.9
He then goes on to explain how C# and Javascript made this very same mistake in slightly different ways. (Python, of course, has phenomenally worse mistakes in its closure capture semantics.)
Perl 5 got this right from the start.
Yup. It's one of those issues that continuously frustrates me when I work with other dynamic languages. There's nothing like writing this monstrosity to get block-level scoping in Javascript:
(function() {
// insert pain here
} )();
I can deal with issues like this in, say, Ruby, because I don't have to write Ruby if I really don't want to. I can't always get away with that in Javascript. (That being said, they're both really cool languages).
Re:Javascript
Aristotle on 2008-09-06T03:52:19
Oh yes, I am not saying these languages suck. (Well, C# kind of excepted, heh.) Goodness knows Perl has its flaws. (I actually like Javascript better in a variety of ways.) It’s just a seemingly minor thing that matters more than one would expect – you really only notice when you miss it, and then it bites hard.