Ich habe mit dem Vorschlag von anonymous herumgespielt, dass alle Mutationen des Objekts ein neues Objekt zurückgeben, und das funktioniert, aber es ist umständlich.
<?php
class FruityEnum {
private $valid = array("apple", "banana", "cantaloupe");
private $value;
function __construct($val) {
if (in_array($val, $this->valid)) {
$this->value = $val;
} else {
throw new Exception("Invalid value");
}
}
function __set($var, $val) {
throw new Exception("Use set()!!");
}
function set(FruityEnum &$obj, $val) {
$obj = new FruityEnum($val);
}
function __get($var) { //everything returns the value...
return $this->value;
}
function __toString() {
return $this->value;
}
}
Und nun zum Test:
function mutate(FruityEnum $obj) { // type hinting!
$obj->set($obj, 'banana');
return $obj;
}
$x = new FruityEnum('apple');
echo $x; // "apple"
$y = mutate($x);
echo $x // still "apple"
. $y // "banana"
Es funktioniert, aber man muss eine seltsame Methode verwenden, um das Objekt zu ändern:
$obj->set($obj, 'foo');
Die einzige andere Möglichkeit, die mir einfällt, wäre die Verwendung der __set()
Methode, aber das war noch schlimmer. Man musste dies tun, was verdammt verwirrend ist.
$obj = $obj->blah = 'foo';
Letztendlich ist es wahrscheinlich einfacher, die Variablen privat zu machen und keine Mutatoren bereitzustellen, so dass die einzige Möglichkeit, den "enum"-Wert einer Variablen zu ändern, darin bestünde, eine neue zu erstellen:
echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");