-
-
Save fredemmott/01ad55c0c03c8d7ba62bbd6e9fb23686 to your computer and use it in GitHub Desktop.
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
<?hh // sort-of | |
trait ImmutableHelper { | |
private function makeMutableCopy(T $object): Mutable<T> { | |
$mutable_t = clone $object; | |
/* ... insert reflection magic here to make all properties mutable ... */ | |
return $mutable_t; | |
} | |
private function makeImmutable(Mutable<T> $object): T { /* similar to above */ } | |
protected function modified((function(Mutable<T>)):mixed) $callback): T { | |
$mutable = $this->makeMutableCopy($this); | |
$callback($mutable); | |
return $this->makeImmutable($mutable); | |
} | |
} | |
class MyImmutableThing { | |
use ImmutableHelper; | |
public immutable ?string $foo = null; | |
// ... | |
public function withFoo(string $foo): MyImmutableThing { | |
return $this->modified($mutable ==> $mutable->foo = $foo); | |
} | |
// ... | |
} |
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
<?hh // sort-of | |
trait ImmutableHelper { | |
protected function withProperty(string $property, mixed $value): this | |
$modified = clone $this; | |
$ro = new ReflectionObject($modified); | |
$rp = $ro->getProperty($property); | |
assert($rp->isImmutable()); | |
$rp->setIsImmutable(false); | |
$rp->setValue($value); | |
$rp->setIsImmutable(true); | |
return $modified; | |
} | |
} | |
class MyImmutableThing { | |
use ImmutableHelper; | |
public immutable ?string $foo = null; | |
// ... | |
public function withFoo(string $foo): MyImmutableThing { | |
return $this->withProperty('foo', $foo); | |
} | |
// ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment