3 ms·
An less-known technique to dealing with nested-ifs is through the use of an one-time loop. Here's an example (in JavaScript): function oneTimeLoopMethod(x)
by buddydvd 15y ago
An less-known technique to dealing with nested-ifs is through the use of an one-time loop. Here's an example (in JavaScript):
function oneTimeLoopMethod(x) {
var result, temp = -1, a, b;
do {
... extra processing code ...
a = func_a(x);
if (!a) break;
... extra processing code ...
b = func_b(a);
if (!b) break;
... extra processing code ...
temp = b;
} while (false);
result = postProcess1(postProcess2(postProcess3(temp))); // This step can be more complicated.
return result;
}
It's useful when you want do additional processing before returning the final result to the caller. Because, otherwise, you'd have to duplicate the processing code in multiple places. When I first read about this technique, its description cautioned about the lack of clarity. So, use it at your own risk!
- Xion 15y agoFunctions that need to employ this trick are often overly complicated and could use splitting into more manageable ones. For one, you could relieve the need of do-while-false itself by moving its content into separate function and replacing break with return.
- buddydvd 15y agoTake this code snippet for example: function func(x) { var a, b, c, result = -1; a = getA(x); if (a) { b = getB(a); if (b) { c = getC(b); if (c) { result = calc(c); release(c); } release(b); } release(a); } return result; } What would you do? Would you create a function for each of the nested block? function func(x) { return _calc1(x, -1); } function _calc1(x, default) { var a = getA(x); if (!a) return default; var result = _calc2(a, x, default); release(a); return result; } function _calc2(a, default) { var b = getB(a); if (!b) return default; var result = _calc3(b, x, default); release(b); return result; } function _calc3(b, default) { var c = getC(b); if (!c) return default; var result = calc(c); release(c); return result; } Or, use guard clauses and write your code like this: function func(x) { var a, b, c, result = -1; a = getA(x); if (!a) return result; b = getB(a); if (b) { release(a); return result; } c = getC(b); if (!c) { release(b); release(a); return result; } result = calc(c); release(c); release(b); release(a); return result; } Instead of doing that, with a do-while-false loop, you can write your code like this: function func(x) { var a, b, c, result = -1; do { a = get(x); if (!a) break; b = get(a); if (!b) break; c = get(b); if (!c) break; result = calc(c); } while(false); if (c) release(c); if (b) release(b); if (a) release(a); return result; } Note that this type of deep nesting are pretty common with Window-based COM programming. They usually go much deeper. With the do-while-false loop technique, you 1.) avoid creating one-time-use helper functions, 2.) consolidate post-processing/clean-up code, 3.) have only one exit point. Can you think of a better way to tackle this problem?