Skip to content

Instantly share code, notes, and snippets.

@fredemmott
Last active September 9, 2016 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fredemmott/01ad55c0c03c8d7ba62bbd6e9fb23686 to your computer and use it in GitHub Desktop.
Save fredemmott/01ad55c0c03c8d7ba62bbd6e9fb23686 to your computer and use it in GitHub Desktop.
<?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);
}
// ...
}
<?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