can i make a (hopefully useful) comment about programming style - something that someone shared with me a long time ago when reading my code that i have found to be very valuable over the years?
it can be incredibly beneficial (for readability, catching logic errors, etc.) to "exit early" from "if" statements. meaning, if you find that you're nesting "ifs" more than a couple of levels deep, the code may be a candidate for flattening.
so - your handleClick function could be rewritten (with stuff removed) as:
var handleClick = function( id )
{
if ( gameOver ) return;
if ( ctrlIsPressed )
{
// do stuff...
return;
}
if ( cell.opened || cell.flagged ) return;
if ( cell.mined )
{
// do stuff...
return;
}
// else do stuff...
if ( cell.neighborMineCount > 0 )
{
// ...
return;
}
// else do final stuff...
}
i may have missed something, but hopefully you get the point. this simple refactoring reduced the depth of the if statements from ~5 to 1. ...many of the other functions could be flattened just like this.
...and how do you know when something can be flattened?
if there is no code after the if statement and the end of the function - just swap the logic and return early.
e.g., this:
var handleClick = function( id )
{
if ( !gameOver )
{
// ...lots of code and if statements...
}
// ...but no code after the block before returning from the function...
}
...turns into this:
var handleClick = function( id )
{
if ( gameOver ) return; // NOTE: logic check change...
// ...do the stuff in the block here...
}
...and this is also a great pattern for checking input variables (and returning or throwing an exception) at the top of the function, ensuring that the code following it has valid input parameters.
since you're sharing your coding projects on your blog (which are excellent) - hopefully you can share this tidbit about coding style with your readers and they'd find it as useful as i have.
Thanks for the kind words, and thanks for sharing! That is a cool pattern. I definitely have a little too much nesting going on in that function, and it could use some refactoring.
I've always felt funny about multiple return statements though, which is probably one reason why a pattern like this doesn't usually come to my mind when considering how to refactor code. I've always liked having one exit point at the end of functions because programmers naturally expect a function to return at the very end. I think minimizing the number of return statements is generally a good thing, but perhaps I have been too strict about applying that rule.
"programmers naturally expect a function to return at the very end"
I disagree. I expect a function to return at the moment the final result is known. The decisions and logic are over. I shouldn't have to glaze over even a single extra line of code, because the work has already been done.
That's a fair point. I guess the main argument in favor of single return statements in modern programming languages is ease of debugging and logging. Like most things in programming, you have to consider the trade-offs. A few return statements isn't the end of the world, but after too many you might just want to make some more functions.
can i make a (hopefully useful) comment about programming style - something that someone shared with me a long time ago when reading my code that i have found to be very valuable over the years?
it can be incredibly beneficial (for readability, catching logic errors, etc.) to "exit early" from "if" statements. meaning, if you find that you're nesting "ifs" more than a couple of levels deep, the code may be a candidate for flattening.
so - your handleClick function could be rewritten (with stuff removed) as:
i may have missed something, but hopefully you get the point. this simple refactoring reduced the depth of the if statements from ~5 to 1. ...many of the other functions could be flattened just like this....and how do you know when something can be flattened?
if there is no code after the if statement and the end of the function - just swap the logic and return early.
e.g., this:
...turns into this: ...and this is also a great pattern for checking input variables (and returning or throwing an exception) at the top of the function, ensuring that the code following it has valid input parameters.since you're sharing your coding projects on your blog (which are excellent) - hopefully you can share this tidbit about coding style with your readers and they'd find it as useful as i have.