Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127384 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id CBEC61A00BC for ; Thu, 15 May 2025 17:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1747331704; bh=DbxqAut4LZkq7pd6YrdbtqqjwftWjDlHnNA4lzbHmnc=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=Ywy8CIiC616/WT7WIcd/v8ffeUxZ4Piiaynjs4yqnsqFUb36VzFQHy3jg/dlXQ3rY EeKMam/UksOqGXuDCHwSNCwl8gQ6LdJ63zB66kBQQYBqoroN1x+9OhuOHtcE1ftwRc M4M7G7NpcsUXEZEfqWQf88mRaHyzu8Yxrsdad5hYz1yRwOvs+heRA3Dxh1Ypl2PtxM a0YdR5gOD+9ZSj1Jv+fXb0/PdbM4w5PzGJbCuO2skHCpTDmrk3+gnhnDnAJy+7L5ht 0OXB/FwVkemImedOcoxvBFntRFAQVMOw+HpL9zsSn0pwALnknmN73wZIiDk1/6crmN CX0ts/02G/zDg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 19465180052 for ; Thu, 15 May 2025 17:55:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_40,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,HTML_MESSAGE, SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail1.25mail.st (mail1.25mail.st [206.123.115.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 15 May 2025 17:55:01 +0000 (UTC) Received: from smtpclient.apple (unknown [49.48.223.253]) by mail1.25mail.st (Postfix) with ESMTPSA id B3E676049A; Thu, 15 May 2025 17:56:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=koalephant.com; s=25mailst; t=1747331831; bh=DbxqAut4LZkq7pd6YrdbtqqjwftWjDlHnNA4lzbHmnc=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=ovr0HgYddi6GRcgHB8D1uF+Rv/EHEJNBStcmqTFrnByJpXXjYtx0B3QCfYdICmsT0 m2qM+lQX7gSEVJEVZsUgTWIarChgPkh6ph5TvSZLjgFfCrX0uKyKq8Db7vJjfMvMl+ MiJWhgLfN+FL5bdNS+/P7vCZ5Ux2jVz3KmroUHKp694oMLOi4R2EIYvws9qmO1e60t LQhOgGTc2LQqiG3RjNLDL/DEC385DENAZOmj2K4X3ZuCJFSwbnN2UaD9KhTWnzqcXa U6t6GnIAkCtRYwOPsOrO/p66KjVNlQ9d172eUqwILY1PtQPUovcBStBOZ/2Be8vBm4 JKxh+e8kiBZzw== Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_9024C92D-C8D3-445D-BF88-D9D566960B32" Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3826.600.51.1.1\)) Subject: Re: [PHP-DEV] [RFC] Clone with v2 Date: Fri, 16 May 2025 00:56:46 +0700 In-Reply-To: Cc: Volker Dusch , Matthew Weier O'Phinney , php internals , =?utf-8?Q?Tim_D=C3=BCsterhus?= To: Andreas Hennings References: <266FA35A-15B0-435E-BBFE-1C6926EB0B7E@koalephant.com> X-Mailer: Apple Mail (2.3826.600.51.1.1) From: php-lists@koalephant.com (Stephen Reay) --Apple-Mail=_9024C92D-C8D3-445D-BF88-D9D566960B32 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On 15 May 2025, at 23:49, Andreas Hennings = wrote: >=20 > On Thu, 15 May 2025 at 13:56, Stephen Reay > wrote: >>=20 >>=20 >>=20 >>=20 >>> On 15 May 2025, at 16:44, Andreas Hennings = wrote: >>>=20 >>> =EF=BB=BFOn Thu, 15 May 2025 at 08:24, Stephen Reay = wrote: >>> [..] >>>>=20 >>>>=20 >>>> I may be missing something here.. >>>>=20 >>>> 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". >>>>=20 >>>> Isn't the previous suggestion of passing the new property arguments = directly to the __clone method the obvious solution to all three = problems? >>>=20 >>> 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. >>>=20 >>> 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. >>>=20 >>> -- Andreas >>>=20 >>>>=20 >>>> 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. >>>>=20 >>>>=20 >>>>=20 >>>> Cheers >>>>=20 >>>> Stephen >>>>=20 >>>>=20 >>>>=20 >>>=20 >>=20 >> 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. >>=20 >> 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. >=20 > 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. >=20 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`.=20 An empty or missing clone method would mean it behaves **exactly the way = it does now**.=20 >>=20 >> 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. >=20 > But they already do that in the ->withXyz() methods. >=20 > 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.=20 > 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. >=20 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. >>=20 >> Additionally it means "clone with" would be usable for non-public = properties at the discretion of the developer writing their code. >=20 > This is already the case, because that "clone with" for non-public > properties can only happen from within methods of the same class > (hierarchy). >=20 > -- Andreas >=20 >>=20 >> 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. >>=20 >> Cheers >>=20 >> Stephen --Apple-Mail=_9024C92D-C8D3-445D-BF88-D9D566960B32 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On 15 May 2025, at 23:49, Andreas Hennings = <andreas@dqxtech.net> wrote:

On Thu, 15 May 2025 at 13:56, Stephen Reay = <php-lists@koalephant.com> wrote:




On 15 = May 2025, at 16:44, Andreas Hennings <andreas@dqxtech.net> = wrote:

=EF=BB=BFOn Thu, 15 May 2025 at 08:24, Stephen Reay = <php-lists@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

= --Apple-Mail=_9024C92D-C8D3-445D-BF88-D9D566960B32--