Re: [RFC] Property hooks, nee accessors
| From: | Larry Garfield | Date: | Mon, 15 May 2023 21:06:25 +0000 |
| Subject: | Re: [RFC] Property hooks, nee accessors | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-120304@lists.php.net to get a copy of this message | ||
On Mon, May 15, 2023, at 8:12 PM, Hendra Gunawan wrote:
>> For the second, the problem with omitting the {} is that it creates yet another syntax
>> variant. That makes it harder for the parser, for static analyzers, for user-space parsing tools
>> like php-parser, etc. That's more work for everyone for fairly little gain.
>
> Sad to read that. Making one of them as the shortest shorthand feels
> like a picky decision. Some people agree with ``
get``. Some
> people
> will argue that ``set` deserves more than
> `get``. Personally, I
> choose ``set`` to be the shortest shorthand as it is more
> relevant
> with constructor property promotion and value object. Do we need a 2nd
> vote for this one?
Secondary votes are generally discouraged. I can see the argument for wanting a short-short version
of set, given how common the validation use case is, but => is almost universally the
"evaluates to" symbol, so using that for a set operation rather than get just feels
weirdly inconsistent. If there were a set-only shorthand, it should be something else.
That said, the ideal for validation would probably be guard clauses, like this, but that would be a
completely different RFC for another time.
function foo(string $name where strlen($name) < 10) { ... }
class Foo {
public function __construct(
public string $name where strlen($name) < 10;
) {}
}
>> What we really would need here is asymmetric visibility. No set hook, but make the
>> property private(set) so that trying to write to it gives an error, as it should.
>
> So if asymmetric visibility is implemented, will my code be this simple?
> ```
> // cache once and freeze,
> // and without additional hidden property
> public private(set) string $prop1 {
> get => $field ??= $this->heavyTask($this->propx, $prop->y);
> }
> ```
If you don't want cache clearing, yes. Ilija also noted to me off-list that you could also
have a set hook that throws an exception rather than just being null, which would also work to
prevent writes.
For clearing that cached value, I think an unset hook is probably the best way, with either
approach.
>> For cache clearing, the best way to do that is probably with an unset hook. That's
>> been omitted from the RFC for now for simplicity, but that sounds like it would be an argument to
>> introduce it later.
>
> I was going to write about this one. IMO, why do we need to provide
> additional hidden properties, when we are able to store the cache
> directly into it? Obviously we need a ``unset`` hook.
I think an unset hook is a fine addition in the future. The way the code is implemented it should
be straightforward to add. However, it feels like scope creep to include it right now, especially
when there are workarounds available. If there's a clear consensus from voters to include it,
though, we can consider that. (Meaning, anyone that would favor including an unset hook now, speak
up or we'll assume it's better to stick with just get/set for now.)
--Larry Garfield