On Tue, May 4, 2021, at 5:33 AM, Nikita Popov wrote:
> Hi internals,
>
> I'd like to present an RFC for property accessors:
> https://wiki.php.net/rfc/property_accessors
>
> Property accessors are like __get() and __set(), but for a single property.
> They also support read-only properties and properties with asymmetric
> visibility (public read, private write) as a side-effect.
>
> The proposal is modeled after C#-style accessors (also used by Swift), and
> syntactically similar to the previous
> https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal.
>
> While I put a lot of effort into both the proposal and the implementation,
> I've grown increasingly uncertain that this is the right direction for us
> to take. The proposal turned out to be significantly more complex than I
> originally anticipated (despite reducing the scope to only "get" and "set"
> accessors), and I'm sure there are some interactions I still haven't
> accounted for. I'm not convinced the value justifies the complexity.
>
> So, while I'm putting this up for discussion, it may be that I will not
> pursue landing it. I think a lot of the practical value of this accessors
> proposal would be captured by support for read-only (and/or private-write)
> properties. This has been discussed (and declined) in the past, but
> probably should be revisited.
>
> Regards,
> Nikita
This is an amazingly detailed RFC, and I love most of it. Thank you, Nikita!
Regarding complexity, can you elaborate on what the most
complex/tricky/problematic parts are? I'm mainly wondering if there are any
parts that could be changed/slightly scaled back that would reduce the
complexity more than it reduces capability. (Eg, removing guard and lazy for
now is a good call, IMO, since both can be emulated with the other two.) All
else equal, though, I would favor including all of it.
I would say that the visibility controls get us 70% of the benefit, not 80/90%,
but I do agree that those are hugely beneficial in and of themselves. *IF* you
decide to scale it back, I would strongly recommend simply dropping the
explicit accessors support and leaving the rest of the syntax the same. That
way we know it's forward-compatible should we decide in the future to
re-introduce explicit accessors.
Some other questions:
1. Do setters have arbitrary access to the object? Can they read/set arbitrary
other values? I'm thinking of something like this:
class Person {
private string $firstName;
private string $lastName;
private string $nickname;
private int $age;
public string $fullName {
get { return "$this->firstName $this->lastName"; }
set($fullName) {
if ($this->age > 50) throw new Exception('You are too old to change your
name.');
[$this->firstName, $this->lastName] = explode(' ', $fullName);
$this->nickname = substr(0, 5, $this->firstName);
}
}
}
(A contrived example, obviously.)
2. My knee-jerk thought is to agree with Marco and avoid references entirely,
for the sake of everyone's sanity. However, it is implied that &get is the
only way to properly handle array property accessors. Am I understanding that
correctly? If not, can you expand on array handling? I'd happily jettison
references if arrays can still be supported nicely without them.
3. The partial incompatibility with constructor promotion is understandable,
but disappointing. Is it at all possible to modify the promotion logic such
that if a property is already defined with accessors, you can still promote it
without a syntax error? I am thinking of this case:
class Test {
private int _$foo;
public int $foo {
get { return $this->_foo; }
set ($foo) {
if ($foo < 0) throw new InvalidArgumentException('Must be positive.');
$this->_foo = $foo;
}
}
public function __construct(public int $foo) {}
}
(Though a guard would be nicer, as it avoids the second variable, but there are
other considerations there.)
4. I still don't love $value being a magic name in setters. Being able to
specify it explicitly is nice, and I would probably always use that myself (and
push for it in coding standards), but would it be feasible to default it
instead to the name of the variable? Since that variable name cannot be a
backing variable, we know that it won't conflict with anything, but it would be
more self-documenting.
Thanks again, and I do hope you can be convinced all this effort is worth
bringing to a vote. :-)
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php