Re: [RFC[ Property accessor hooks, take 2

From: Date: Sat, 16 Mar 2024 08:32:39 +0000
Subject: Re: [RFC[ Property accessor hooks, take 2
References: 1 2 3 4 5 6 7 8  Groups: php.internals 
Request: Send a blank email to internals+get-122653@lists.php.net to get a copy of this message
On 16 March 2024 00:19:57 GMT, Larry Garfield <larry@garfieldtech.com> wrote: >Well, reading/writing from within a set/get hook is an obvious use case to support. We cannot >do cached properties easily otherwise: > >public string $expensive { > get => $this->expensive ??= $this->compute(); > set { > if (strlen($value) < 50) throw new Exception(); > $this->expensive = $value; > } >} To play devil's advocate, in an implementation with only virtual properties, this is still perfectly possible, just one declaration longer: private string $_expensive; public string $expensive { get => $this->_expensive ??= $this->compute(); set { if (strlen($value) < 50) throw new Exception(); $this->_expensive = $value; } } Note that in this version there is an unambiguous way to refer to the raw value from anywhere else in the class, if you wanted a clearAll() method for instance. I can't stress enough that this is where a lot of my thinking comes from: that backed properties are really the special case, not the default. Anything you can do with a backed property you can do with a virtual one, but the opposite will never be true. The minimum version of backed properties is basically just sugar for that - the property is still essentially virtual, but the language declares the backing property for you, leading to: public string $expensive { get => $field ??= $this->compute(); set { if (strlen($value) < 50) throw new Exception(); $field = $value; } } I realise now that this isn't actually how the current implementation works, but again I wanted to illustrate where I'm coming from: that backed properties are just a convenience, not a different type of property with its own rules. > Being the same also makes the language more predictable, which is also a design goal for this > RFC. (Hence why "this is the same logic as methods/__get/other very similar thing" is > mentioned several times in the RFC. Consistency in expectations is generally a good thing.) I can only speak for myself, but my expectations were based on: a) How __get and __set are used in practice. That generally involves reading and writing a private property, of either the same or different name from the public one; and that private property is visible everywhere equally, no special handling based on the call stack. b) What happens if you accidentally cause infinite recursion in a normal function or method, which is that the language eventually hits a stack depth limit and throws an error. So the assertion that the proposal was consistent with expectations surprised me. It feels to me like something that will seem surprising to people when they first encounter it, but useful once they understand the implications. Regards, Rowan Tommins [IMSoP]

« previous php.internals (#122653) next »