immutable-object icon indicating copy to clipboard operation
immutable-object copied to clipboard

[Feature] Allow "write once" initialization of fields

Open lisachenko opened this issue 5 years ago • 5 comments

Logic of typed properties requires initialization and engine allows to initialize such properties from everywhere, not only within constructor.

@nikic has suggested to follow this logic, eg. allow to initialize each property only once. Such implementation will allow to call private/protected setters with additional logic of initialization/validation.

lisachenko avatar Feb 13 '20 12:02 lisachenko

By Nikita:

For example, people may wish to use newInstanceWithoutConstructor() + manual property initialization for custom serialization libs etc. Or even the same internally (unserialization, PDO fetch object, etc). These things are hard (impossible?) to make work if you introduce restrictions about constructors.

lisachenko avatar Feb 13 '20 12:02 lisachenko

By the way, this is a common pattern for immutable objects

public function withRed(int $red): self
{
    assert($red >= 0 && $red <= 255);
    $color = clone $this;
    $color->red = $red;
    return $color;
}

Does this enhancement can may work it at least with

public function withRed(int $red): self
{
    assert($red >= 0 && $red <= 255);
    $color = clone $this;
    unset($color->red);
    $color->red = $red;
    return $color;
}

?

unset($this->foo); is legit way to make property uninitialized in new PHP versions, AFAIK.

unkind avatar Aug 24 '20 12:08 unkind

I also have this case :)

fefas avatar Sep 28 '20 20:09 fefas

I’m surprised that you have these cases 😃 Currently only ctor and static methods are allowed, sorry. But your comment was like small inspiration ))

PS. Not sure, if I’ll be able to return to my projects soon. Very busy on my new work...

lisachenko avatar Sep 28 '20 21:09 lisachenko

@lisachenko no problem, I would like to have more time as well. So, I could contribute to the package. I think what you did is a really good work.

Just to explain a bit about my case: we need to keep the historical change log of an entity and there are many actions that have to be performed upon a version of the entity. The way we are doing it is by making the entity immutable and, everytime you need to update a field, we have this withSomethingMethod that basically clones the object, changes what is needed, and returns the new instance.

We could of course use a contructor for it, but cloning and chaging makes the implementation a bit cleaner. I see your point of restricting mutability only within ctor and static methods and I actually agree with it, but I was wondering if there could be a solution that would be useful in our case.

fefas avatar Sep 29 '20 09:09 fefas