Hi
Apologies for the belated reply. I was busy with getting my own
implementation wrapped up and the thread was so active that I had
troubles keeping up.
On 7/11/25 06:20, Nick wrote:
Personally, I would really like to have `get` hooks on readonly properties.
Please consider something like this:
```php
readonly class Foo
{
public function __construct(
public Output $style,
public string $some {
get => Output::One === $this->style ? ucfirst($this->some) :
strtoupper($this->some);
set => '' !== $value ? $value : throw new \Exception();
}
) {}
}
```
Easy-to-digest one-liners. Concerns remain separated. Set takes care of
validation, get formats.
I respectfully disagree on the "easy-to-digest" part. A 98 character
line containing logic is not easy to digest.
If `get` would not be allowed, we couldn’t do such an obvious thing. For what
reason?
In *this specific instance* the `get` hook would not violate my
expectations, but this is not true in general.
Instead we would need to delegate formatting to the `set` hook which is messy.
Running formatting for every access is messy. And it's messy to
needlessly use hooks for something that can just be constructor logic.
Since `$some` is *always* assigned when running the constructor, this
can just be:
readonly class Foo {
public string $some;
public function __construct(
public Output $style,
string $some,
) {
if ($some === '') {
throw new \Exception();
}
$this->some = match ($style) {
Output::One => ucfirst($some),
default => strtoupper($some),
};
}
}
Making `Foo` a plain old data class without any behavior after
construction and with very obvious control flow within the constructor.
This results in both more efficient and easier to reason about code.
Best regards
Tim Düsterhus