On Fri, 21 Feb 2020 at 23:18, Larry Garfield <[email protected]> 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]