> On 15 May 2025, at 23:49, Andreas Hennings <andr...@dqxtech.net> wrote: > > On Thu, 15 May 2025 at 13:56, Stephen Reay <php-li...@koalephant.com > <mailto:php-li...@koalephant.com>> wrote: >> >> >> >> >>> On 15 May 2025, at 16:44, Andreas Hennings <andr...@dqxtech.net> wrote: >>> >>> On Thu, 15 May 2025 at 08:24, Stephen Reay <php-li...@koalephant.com> >>> wrote: >>> [..] >>>> >>>> >>>> I may be missing something here.. >>>> >>>> So far the issues are "how do we deal with a parameter for the actual >>>> object, vs new properties to apply", "should __clone be called before or >>>> after the changes" and "this won't allow regular readonly properties to be >>>> modified". >>>> >>>> Isn't the previous suggestion of passing the new property arguments >>>> directly to the __clone method the obvious solution to all three problems? >>> >>> What exactly should happen then? >>> Would the __clone() method be responsible for assigning those properties? >>> Or does the __clone() method get the chance to alter the values before >>> they are assigned? >>> (this would mean they have to be passed by reference) >>> I think this last option is the best, because the values in the array >>> can be changed without any readonly constraints. >>> >>> Another option I was thinking of would be to call __clone() after the >>> changes are applied, and pass both the original object and the array >>> of changes as first parameter. >>> But I think this is a dead end. >>> >>> -- Andreas >>> >>>> >>>> There's no potential for a conflicting property name, the developer can >>>> use the new property values in the order they see fit relative to the >>>> logic in the __clone call, and it's inherently in scope to write to any >>>> (unlocked during __clone) readonly properties. >>>> >>>> >>>> >>>> Cheers >>>> >>>> Stephen >>>> >>>> >>>> >>> >> >> I would suggest that the __clone method should be directly responsible for >> making any changes, just as it is now when it comes to deep cloning or >> resetting values. >> >> Yes I realise it means developers need to then opt in and provide the >> functionality to support `clone $foo with(bar: "baz")` or whatever syntax is >> used. > > I don't really like this. > It would mean that if you add an empty __clone() method, it would > prevent all of the automatic setting of values. >
To repeat myself: yes. It requires the class developer to opt-in to supporting this feature of the language. Just the same way promoted constructor parameters are opt-in, and don't just create a bunch of properties with the names the caller specified to `new`. An empty or missing clone method would mean it behaves **exactly the way it does now**. >> >> If the properties are public properties, there's nothing stopping someone >> writing their own clone_with() in userland now; If someone is using >> readonly properties I'd suggest they want to specifically manage updates to >> those properties themselves anyway. > > But they already do that in the ->withXyz() methods. > > A public non-readonly property can be set from anywhere without > validation or clean-up, so by default the __clone() method would want > to leave it alone. Again, what happens when cloning should be entirely the purview of the developer that writes the class. > A readonly or non-public property can only be initialized from within > the class, so the ->withSomething() method would be the place for > cleanup and validation. > The default behavior of an empty __clone() method should therefore be > to just allow all of the properties being set as they would be without > a __clone() method. > 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. >> >> Additionally it means "clone with" would be usable for non-public properties >> at the discretion of the developer writing their code. > > This is already the case, because that "clone with" for non-public > properties can only happen from within methods of the same class > (hierarchy). > > -- Andreas > >> >> The mental model is also very clear with this: copy the object in memory, >> and then call __clone(), with the arguments passed to the clone action - >> which may be none in the case of code that doesn't accept any clone >> arguments. The only change from the current model is that it *may* be >> passing arguments. >> >> Cheers >> >> Stephen