Created
November 1, 2012 03:33
-
-
Save gbluma/3991490 to your computer and use it in GitHub Desktop.
Code examples for http://garrettbluma.com/2012/10/05/exhaustive-pattern-matching-in-php/
This file contains hidden or 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
<var> = match( <search_term> , <enumerations> ) | |
->option( <possible_term> , <function> ) | |
->option( <possible_term> , <function> ) | |
->option( "_", <function> ) | |
->exec(); |
This file contains hidden or 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
switch ("INIT") { | |
case "INIT": $msg = "program is initializing"; break; | |
case "END": $msg = "program is ending"; break; | |
} |
This file contains hidden or 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
$statuses = array("INIT","END"); | |
$msg = match("INIT", $statuses) | |
->option("INIT", function () { return "program is initializing"; } ) | |
->option("END", function () { return "program is ending"; } ) | |
->exec(); |
This file contains hidden or 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
$statuses = array("INIT","PROCESSING","END"); |
This file contains hidden or 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
$msg = match("INIT", $statuses) | |
->option("INIT", function () { return "program is initializing"; } ) | |
->option("PROCESSING", function() { return "program is running"; } ) | |
->option("END", function () { return "program is ending"; } ) | |
->exec(); | |
// => No Errors |
This file contains hidden or 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 Matcher { | |
private $cases = array(); | |
function __construct($target, $source) { | |
$this->target = $target; | |
$this->source = $source; | |
} | |
public function option($p,$f) { | |
$this->cases[$p] = $f; | |
return $this; | |
} | |
public function exec() { | |
// check that element is in search set | |
if (!isset($this->cases[$this->target])) { | |
// do we have a catch-all? | |
if (isset($this->cases['_'])) { | |
// ... yes, use catch all. | |
return $this->cases["_"](); | |
} else { | |
// ... no, throw error. | |
throw new Exception("Search term not found."); | |
} | |
} | |
if (!isset($this->cases['_'])) { | |
// check for exhaustive matching | |
foreach($this->source as &$s) { | |
if (!isset($this->cases[$s])) { | |
throw new Exception("$s option not covered" | |
. " in exhaustive pattern match"); | |
} | |
} | |
} | |
// we can assume that we have a match return | |
$this->cases[$this->target](); | |
} | |
} | |
// convenience function to simplify implementation | |
function match($target, $source) { | |
$o = new Matcher($target, $source); | |
return $o; | |
} |
This file contains hidden or 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 | |
// normally we would see something like this. | |
switch ("INIT") { | |
case "INIT": $msg = "program is initializing"; break; | |
case "END": $msg = "program is ending"; break; | |
} | |
/* | |
* The problem with this is that we don't know when something is legitimately | |
* broken. We assume that any unknown status can be ignored. This is bad. | |
*/ | |
$statuses = array("INIT","END"); | |
$msg = match("INIT", $statuses) | |
->option("INIT", function () { return "program is initializing"; } ) | |
->option("END", function () { return "program is ending"; } ) | |
->exec(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment