Live data from Hacker News

How One Missing `var` Ruined our Launch

blog.meloncard.com

81–90 of 223 posts

Re: How One Missing `var` Ruined our Launch

#82

One thing you can do to help avoid this: use JSLint (or something equivalent) to check for missing var keywords. And, the obvious (as you already mentioned) coffeescript. Would love to hear of other suggestions on how to effectively debug this, especially in node.

JSLint was my first response, but I have to agree with someone higher up -- use strict is probably a better solution, since it'll happen whether you like it (or forget it) or not.

using strict sounds like a great idea - I wonder what other implications that has, need to look into it.

Re: How One Missing `var` Ruined our Launch

#83

JS is so easy to cock up in, I commonly find myself logging to the console just to make myself sure of the scope and other things. This technique totally went to shit when I came across one of our scripts that gratuitously used `apply()` all over the place. The other common error is array iteration, and I've not quite understood why iterating through one array in the same scope as where it was created works fine, but…

if you want to filter out prototypes you can use object.hasOwnProperty( property )

Re: How One Missing `var` Ruined our Launch

#84
post #48

Why has it become popular for dynamic languages to conflate establishing a binding with assigning it a new value? Ruby, Python, and Javascript are all guilty of this. Scheme got it right sometime in the 1970's. (let ((x initial-value)) ; binding (set! x new-value)) ; assignment Or in infix syntax (Dylan): let x = initial-value ; x := new-value ;

Python doesn't let you write outside of local scope without a special keyword. Exactly the inverse of JS. If you want to write to global state, and you're aware that you're writing to global state, then you use the "global" keyword. That's all.

Python implicitly binds to the innermost scope on assignment, so you had the opposite problem when you wanted to reach a nested, non-global scope. Hence the nonlocal keyword added in py3k.

http://www.python.org/dev/peps/pep-3104/

Re: How One Missing `var` Ruined our Launch

#85
"I would posit here that nothing I could do in best practice (manual front-end testing, unit testing, error handling, etc.) would have caught the offending line."

Running your code through JSLint (or something similar) would have been helpful here. Performing this check before committing code is considered a best practice and it's really easy to setup a pre-commit hook in most version control systems. JSLint has a Node.js mode. It would have said something like "variable used before being defined". http://www.jslint.com/

Re: How One Missing `var` Ruined our Launch

#86
post #15
post #5

Reminds me of one of the more confusing bugs I've ever encountered in my life. I was throwing together a quick UI with Adobe Flex, and for some reason every time you clicked a particular button, the entire UI would shift 20 or so pixels to the right. I spent hours scratching my head until I noticed this for loop: for (x=0;x I wasn't declaring the x variable, so it was using the x part of the x/y positioning of the UI…

Ha, that reminds me of a program I was writing in MATLAB. I used `i` for a loop index in one part of the script and then later when doing some complex number calculations (`2 + 3i`)...it was one of those so-stupid-you-have-to-laugh moments when I finally figured it out.

It's for this precise reason that I use 1i rather than i when doing complex arithmetic in matlab.

Re: How One Missing `var` Ruined our Launch

#87
post #48

Why has it become popular for dynamic languages to conflate establishing a binding with assigning it a new value? Ruby, Python, and Javascript are all guilty of this. Scheme got it right sometime in the 1970's. (let ((x initial-value)) ; binding (set! x new-value)) ; assignment Or in infix syntax (Dylan): let x = initial-value ; x := new-value ;

Yes. The other thing Scheme got right is explicit variable scope

    (define x 42) ;; global
    (let ((x 42)) ;; local, only defined inside the enclosing parenthesis. 
      (+ x x))

Re: How One Missing `var` Ruined our Launch

#88

Earlier quoted context omitted.

Not to sound harsh, followed by something quite sarcastic and judgemental isn't a particularly nice way to address someone you don't know. I for one would speculate, not to sound harsh, that if you haven't made silly errors like this then you haven't been around the block enough times.

> I for one would speculate, not to sound harsh, that if you haven't made silly errors like this then you haven't been around the block enough times. on the other hand, those of us who have been around the block enough times have almost certainly encountered co-workers who were bright, talented, cute, whatever - but at the end of the day were just ... sloppy ... lazy ... careless ... in their approach. It's a persona…

"...never learned to by hyper-vigilant..."

My eyebrow just raised so far my forehead cramped.

Re: How One Missing `var` Ruined our Launch

#89
post #63

Earlier quoted context omitted.

Yeah, that's all he needed. Making it a comment isn't necessary either. Maybe Node should be strict by default? I can understand it not being the case for browsers that need to support legacy code, but for Node it doesn't really need to care about that.

Huh. On the scale from pragmatic idiosyncrasy to simply bizarre, making a string literal expression change the runtime behaviour in that manner is fairly wide towards the bizarre end of the scale. I think, if anything, requiring it to be in a comment would have been less odd; at least comments imply a sense of "meta"-ness.

Yeah, I always thought the string idea was wacko too, but introducing a new keyword in a language that has to be backwards compatible or suffer doom isn't a good idea either.

Re: How One Missing `var` Ruined our Launch

#90
post #48

Why has it become popular for dynamic languages to conflate establishing a binding with assigning it a new value? Ruby, Python, and Javascript are all guilty of this. Scheme got it right sometime in the 1970's. (let ((x initial-value)) ; binding (set! x new-value)) ; assignment Or in infix syntax (Dylan): let x = initial-value ; x := new-value ;

Io has a similar distinction. In the Io language, := is syntax sugar for newSlot and = only means updateSlot. So if you accidently = a slot that doesn't exist, it doesn't new-up a magic global, it raises an error.
Post reply on HN