Skip to content

Instantly share code, notes, and snippets.

@gbluma
Created November 1, 2012 03:33
Show Gist options
  • Save gbluma/3991490 to your computer and use it in GitHub Desktop.
Save gbluma/3991490 to your computer and use it in GitHub Desktop.
<var> = match( <search_term> , <enumerations> )
->option( <possible_term> , <function> )
->option( <possible_term> , <function> )
->option( "_", <function> )
->exec();
switch ("INIT") {
case "INIT": $msg = "program is initializing"; break;
case "END": $msg = "program is ending"; break;
}
$statuses = array("INIT","END");
$msg = match("INIT", $statuses)
->option("INIT", function () { return "program is initializing"; } )
->option("END", function () { return "program is ending"; } )
->exec();
$statuses = array("INIT","PROCESSING","END");
$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
<?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;
}
<?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