I didn't like the Prefix-style
syntax. I prefer the
Hook-embedded-style
syntax. First let's look at the counterpoints of the
Prefix-style
syntax:
## 1) "Prefix-style
is more visually scannable"
> The set visibility is 10 lines away from the get visibility!
Solution:
```php
class HookEmbeddedStyle
{
public string $phone {
private set {
$this->phone = implode('', array_filter(fn($c) => is_numeric($c),
explode($value)))
}
get {
if (!$this->phone) {
return '';
}
if ($this->phone[0] === 1) {
return 'US ' . $this->phone;
}
return 'Intl +' . $this->phone;
}
}
}
```
The set visibility is not 10 lines away from the get visibility if you put it at the top. For me
this is about code convention, not about syntactic structure:
only put the hook with explicit visibility at the top, when some of the hooks do not have explicit
visibility!
## 2) "Prefix-style
is shorter"
```php
public private(set) string $name;
public string $name { private set; }
```
Irrelevant to consider 1-2 characters.
If you break the lines needed for the hook block, the line (the horizontal size) is smaller when
using Hook-embedded-style
and in my opinion it is more readable because there is less
information per line:
```php
public private(set) string $name;
public string $name {
private set;
}
```
## 3) "Prefix-style
doesn't presume a connection with hooks"
> As noted above in "Interaction with hooks", visibility controls exist independently
> of hooks.
I agree, but with Property Hooks, this should now define the overall visibility only. Like a bigger
gate that you open, and there are other doors defining the visibility of the operations get, set
(hooks).
> In fact, as implemented, they don't interact at all. Using hook syntax for visibility
> controls is therefore surprising and confusing.
Why "surprising and confusing"? I see hooks as a different kind of function/method.
Property Hooks RFC shouldn't pass without requiring hook parentheses, for any hook when the
property is not abstract. The $value
in the set
hook seems to come out of
nowhere to some people (the exception is for hooks declared on an abstract property which you can
define without parameters and thus you are free to define whatever parameters you want on the
concrete property).
When you define a method in PHP, it should be possible to omit the "function", but the
parameters should be required because that's the nature of a function/method: to have
parameters.
## 4) "It's non-obvious in Hook-embedded-style
what hook behavior should be
implied"
> ...So “arrays with hooks can do less” is already an established fact of the language.
> However, if the hook-style syntax is used for visibility:
```php
class A
{
public array $arr { protected set; }
}
class B extends A
{
public function add(int $val)
{
// Should this be legal?
$this->arr[] = $val;
}
}
$b = new B();
$b->add(5);
```
First of all: non-abstract property hook must have a body.
Second: when asymmetric visibility is explicit, it means that symmetric visibility is implicit: a
declared hook that does not have declared visibility has the same general visibility as the
property, in this case: public.
Third:
There's another limitation on hooks here that makes things a bit confusing: there's a
missing hook for a specific operation because you can clearly separate the set
from the
push
operation...
Solution:
```php
abstract class A
{
abstract public array $arr {
push; // Hook available only for "array" type properties only; public
visibility
private set;
}
}
class B extends A
{
public array $arr {
push ($value) { // public push ....
here is redundant
// Mandatory to implement logic here.
}
private set ($value) {
// Mandatory to Implement logic here.
}
}
public function __construct ()
{
// Legal ✅ (set hook is protected)
$this->arr = [1]; // call set hook
}
public function add(int $value)
{
// Legal ✅ (push hook is public)
$this->arr[] = $value; // call push hook
}
}
$b = new B();
$b->add(5);
$b->arr; // Legal ✅ (Inherited from the general visibility that is public)
$b->arr = [1, 2, 3]; // Fatal error ❌ - access to set hook is private only
$b->arr[] = 4; // Legal ✅ - call public push hook
```
My point: Prefix-style
is not future-proof
## 1) The Prefix-style
is not compatible with new hooks
If more hooks are added in the future, such as the push
hook for arrays or even a hook
that is compatible with all types such as init
, Hook-embedded-style
will
become compatible, but Prefix-style
not.
## 2) Hook overloading
If hook overloading is added in the future, Prefix-style
would not be supported to have
this granular visibility into operations. For example, it might be possible to add a public hook and
a protected hook for the same operation, where one would be triggered if the operation occurred from
outside the class, and the other if the operation occurred from inside the class.
Em 10 de jun. de 2024 13:15 -0300, Tiffany <[email protected]> escreveu:
>
> > On Wed, May 29, 2024, 2:16 PM Larry Garfield <[email protected]> wrote:
> > > As promised, Ilija and I offer this revised version of asymmetric visibility.
> > >
> > > https://wiki.php.net/rfc/asymmetric-visibility-v2
> > >
> > > It's still essentially the same as last year's version, but with a few
> > > adjustments and changes:
> > >
> > > * readonly properties are now supported in a logical fashion.
> > > * We've brought back the abbreviated form, as public-read, something else set is
> > > the most common use case.
> > > * The section on magic methods has been greatly simplified. The implementation
> > > itself hasn't changed, but the explanation is a lot less confusing now.
> > > * We've explained how aviz interacts with hooks (they don't, really) and
> > > with interface properties (in the obvious way), which didn't exist at the time of the last
> > > draft.
> > > * We've added a section with examples of how aviz is a concrete improvement,
> > > even in a world with readonly and hooks.
> > > * We've added a section discussing why the prefix-style syntax was chosen.
> > >
> > > *dons flame retardant suit*
> > >
> > > --
> > > Larry Garfield
> > > [email protected]
>
> Sending an email to quickly enable a new mailing list subscriber to engage in the conversation.