On Fri, 21 Feb 2020 at 23:18, Larry Garfield <la...@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]

Reply via email to