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]