Re: [RFC] Asymmetric visibility
| From: | Stephen Reay | Date: | Mon, 08 Aug 2022 09:09:57 +0000 |
| Subject: | Re: [RFC] Asymmetric visibility | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-118385@lists.php.net to get a copy of this message | ||
> On 6 Aug 2022, at 00:08, Larry Garfield <larry@garfieldtech.com> wrote:
>
> Ilija Tovilo and I are happy to present the first new RFC for PHP 8.3: Asymmetric Visibility.
>
> https://wiki.php.net/rfc/asymmetric-visibility
>
> Details are in the RFC, but it's largely a copy of Swift's support for the same.
>
> --
> Larry Garfield
> larry@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
Hi Larry,
I like most of this, but I have one disagreement.
Can you expand a bit more on the reasoning for restricting the ability to combine __set() here?
The RFC states that it’s to keep consistency with
readonly, because __set on a
readonly property that’s initialised throws an error - but isn’t that because of the nature of
it being readonly, rather than because of the visibility rules? The error given is "Cannot
modify readonly property” thrown from within the __set() method, not "Cannot access protected
property” thrown from the outside calling context, when the __set() method is not implemented.
If I set a property to readonly I would expect it to not be settable after initialisation,
regardless of visibility, whether it’s via direct access or via __set, etc. (i.e. what readonly
does now)
But if I set a property to public private(set) for example, I would **expect** that the
__set method on that class (or in the hierarchy if using protected(set)) would be called when
setting it from an inaccessible context, just as it would be called when setting a regular protected
property.
It seems very unintuitive to me, that the first example here would work, but that the second would
not work:
class Foo {
protected readonly int $bar;
public function __set(string $name, mixed $value): void {
$this->{$name} = $value;
}
}
$a = new Foo;
$a->bar = 1;
class Bar {
public protected(set) int $baz;
public function __set(string $name, mixed $value): void {
$this->{$name} = $value;
}
}
$b = new Bar;
$b->baz = 1;
Cheers
Stephen