Last active
April 28, 2018 18:49
-
-
Save mikeschinkel/d0e2b3892a5422fb5c729c989b87782a to your computer and use it in GitHub Desktop.
Example of using do{...break...}while(false); vs. early return; Modifying: https://twitter.com/gonedark/status/923557577593458689 My code has become significantly more robust since I started using this technique.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Set { | |
private $items = []; | |
public function add($item) | |
{ | |
/* | |
* This construct makes early exit explicit. We bracket the early exit logic. | |
*/ | |
do { | |
/* | |
* Initializing a return value to appropriate value in case guard clauses | |
* result in a break. | |
*/ | |
$added = false; | |
/* | |
* We strive for guard clauses that are as simple as we can make them. | |
*/ | |
if ($item === null) { | |
break; | |
} | |
/* | |
* Simple expressions are easier to reason about thus more readable. | |
*/ | |
if ($this->contains($item)) { | |
break; | |
} | |
/* | |
* No branching logic except for breaks makes it clear that the guarded logic | |
* is after the guard clauses and above the "while (false)" | |
*/ | |
$this->items[] = $item; | |
/* | |
* Change return value to indicate success | |
*/ | |
$added = true; | |
/** | |
* Overall this approach makes it less painful to add more guard clauses making | |
* code more likely to be more robust. In my experience anyway. | |
*/ | |
} while (false); | |
/* | |
* Here we have a single return where we can set an XDEBUG breakpoint. Hurrah! | |
*/ | |
return $added; | |
} | |
// ... | |
} |
I think using goto
doesn't make the code readable because the goto
will be forced to go to the specified line.
We normally look the code is line-by-line.
goto
is an unstructured branching mechanism. This is a structured branching mechanism. I just wish PHP allowed us to omit the while (false);
, or provided a different control structure such as sequence { ... }
or try { ...}
w/o the required catch (...) {}
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is just a thinly veiled use of
goto
, which would be much easier to read if you instead actually usedgoto
.