Re: RFC: Records
| From: | Rob Landers | Date: | Thu, 17 Jul 2025 06:52:34 +0000 |
| Subject: | Re: RFC: Records | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-128092@lists.php.net to get a copy of this message | ||
On Tue, Jul 15, 2025, at 19:05, Nicolas Grekas wrote:
> Not sure it's really a contribution to the discussion but in case you missed it, you can
> make public properties "public(set)":
>
> final readonly class Response {
> public function __construct(
> public public(set) int $statusCode,
> public public(set) string $reasonPhrase,
> // ...
> ) {
> if($this->statusCode >= 600) {
> throw new LogicException();
> }
> }
> }
>
> Then your example works.
> That's ugly, but that doesn't have to stay that way.
> And I'm now wondering why is that not the default?
>
> Nicolas
It "works" but it still results in an invalid state (statusCode >= 600 is never
thrown). Previously, this kind of invalid object would only be possible via reflection and skipping
the constructor. Now, we have a copy, without a copy-constructor to perform any validation or error
checking before the copy completes; so basically invalid objects are incredibly easy/accidental to
be made, unless everyone starts changing all validation to be done in getters/setters (which is not
possible on readonly objects) or by keeping things protected(set) and ensuring that only specific
functions set them... and probably make every readonly class final.
— Rob