Re: [RFC] [DISCUSSION] Immutable/final/readonly properties

From: Date: Mon, 24 Feb 2020 13:55:21 +0000
Subject: Re: [RFC] [DISCUSSION] Immutable/final/readonly properties
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-108736@lists.php.net to get a copy of this message
On Fri, 21 Feb 2020 at 23:18, Larry Garfield <larry@garfieldtech.com> wrote: > The with*() method style requires cloning the object. What happens to the > locked status of a set property if the object is cloned? Are they then > settable again, or do they come pre-locked? > > Neither of those seem good, now that I think about it. If they come > pre-locked, then you really can't clone, change one property, and return > the new one (as is the standard practice now in that case). If they don't > come pre-locked, then the newly created object can have everything on it > changed, once, which creates a loophole. I'm not sure what the right > answer is here. > As with typed properties, I wonder if there's a way we can introduce a new initialisation sequence for objects, so that there's a specific point where the object is considered "fully constructed" after new or clone. A couple of brainstormed ideas, with plenty of downsides I'm sure: An explicit finalise() function or keyword public function withFoo($foo) { $inst = clone $this; // all readonly properties are initially "unlocked" $inst->foo = $foo; // now lock them, perhaps also checking that no typed properties are left uninitialised finalise($inst); // or finalise $inst; return $inst; } A special code block: public function withFoo($foo) { $inst = clone $this { // all properties are "unlocked" within this special block $inst->foo = $foo; }; // from here onwards, readonly properties can't be written to return $inst; } Perhaps could also be used with constructors: public function createFromOtherThing(OtherThing $other) { $inst = new static('some parameter') { // readonly properties can be written in the constructor, or within this block $inst->foo = $other->getFoo(); }; // object is "finalised" when the block ends return $inst; } Regards, -- Rowan Tommins [IMSoP]

« previous php.internals (#108736) next »