On 15/05/2025 18:56, Stephen Reay wrote:
I agree that no __clone and an empty __clone should behave the same way. But as I said, I believe they should behave the same way as they do *now*, until the developer opts in to support cloning with new values.
I think what Andreas is saying is that the behaviour of this:
$foo = clone($bar, someProperty: 42);
Should be consistent with the existing behaviour of this:
$foo = clone $bar;
$bar->someProperty = 42;
An empty or missing __clone method won't prevent someProperty
being assigned in the existing case, and for everything other than readonly properties, the new syntax is purely sugar for the existing one.
If I understand the RFC, the only change in behaviour is for readonly properties, which are "unlocked" during the "clone with" process. That means that if they were previously validated only in the constructor, this syntax can put the object in an unexpected state.
However, readonly properties are "protected(set)" by default, so the situations where this can happen are actually quite limited:
- Code inside the class itself (private scope) can reasonably be considered to be "opting in" to the feature it's using.
- Code in a sub-class (protected scope) can by default over-ride the constructor anyway.
- Code outside the class (public scope) will fail unless the property is explicitly "readonly public(set)", which would be pointless if it was always initialised in the constructor.
So the only case I can think of where something surprising could happen is:
1. A public or protected readonly property is initialised in a constructor marked "final"
2. A sub-class adds code that uses "clone with" to set that property to a new value
The question then is, how worried are we about that scenario?
--
Rowan Tommins
[IMSoP]