Hi

On 4/24/23 01:01, Máté Kocsis wrote:
2) How does this interact with an __clone() method? I'm guessing the
__clone() would be called first, and then the with-clause applied?


Yeah, thanks for pointing this out! I agree that the clarification is very
much needed. BTW the evaluation order
is exactly how you wrote. This is now added to the RFC.

Tim wrote:

In which order will __clone(), foo(), bar(), quux(), baz() be evaluated
and what will happen if one of them throws an Exception? Will
destructors of the cloned object run? When?


In fact, after the initial ZEND_CLONE opcode (which possibly invokes
__clone()), a separate opcode is generated for each
assignment (the newly added ZEND_CLONE_INIT_PROP). This means that foo(),
bar(), quux(), and baz() will be evaluated
in this very order. If any of them throws an exception, evaluation stops
and the assignments are not rolled back.

Regarding the destructors: yes, the destructor of the cloned object runs
immediately. In order to make sure, I've just added a test case:
https://github.com/php/php-src/pull/9497/commits/4d184f960ac1b5590d87739ee3278c13fac157de
I hope that this result is what
you expect.

I'm combining your two replies, as they are related: The behavior is what I expected. It would however be useful if you also added an explicit example with side effects to "Interaction with the __clone magic method" section in the RFC and the tests (just 'echo __FUNCTION__' or so) to make it explicit. I believe the attached example should do the trick. If I understand correctly the output should be:

__clone
a
b
c
d
unhandled exception
__destruct
__destruct

I'd rather see only the fat-arrow being allowed. Unless I'm missing
something, braces with colon is not used anywhere else, whereas braces +
'=>' is known from match() and '=>' more generally is already used with
array literals [1]. Having two similar syntaxes for the same thing is
not great when both are commonly needed is not great. They need to be
documented and learned by developers.


I can only repeat what Rowan answered, since I agree with it completely:

I think it makes sense to have an unquoted form here, because the common
case is that they are names which analysers can match statically to
particular properties, not strings which will be analysed at runtime. There
are plenty of places in the language where dynamic names are allowed, but
we don't just use strings for the static case

A static analyzer should be able to understand a string literal.


However, I'm not completely sold on making "clone with" look like a
function call (return clone $this with (a: 1);), but
at least I like it more than using an array-like style (return clone $this
with [a: 1];). My intention with
using curly brackets (return clone $this with {a: 1};) is to highlight the
fact that it is a map
of key-value pairs, similarly how the JSON standard does so. Not to mention

To a PHP programmer, a map of arbitrary key-value pairs is an array. That's what is familiar to every PHP programmer and thus an array literal should feel reasonably natural and obvious with regard to semantics (that's why it was my suggestion).

The named parameters syntax is fairly new, but at least there is precedent and thus developers are able to transfer their existing knowledge.

Both would be able to completely replace the Foo::withProperties() example by means of existing syntax (either bare array or named parameter destructuring) and without the overhead of repeated cloning.

The brace + colon syntax is a completely new invention and less flexible as shown by the need to use a different separator character to differentiate between bare names and global constants.

that "clone with" serves a very
similar purpose to object initializers, and the different languages I know
to have this feature use
a similar syntax (Java: http://wiki.c2.com/?DoubleBraceInitialization, C#:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers#object-initializers
).

Different languages, different syntax choices and different existing syntax. I don't do C#, but I'm sure that the C# syntax totally makes sense in the context of C#. I do not believe it makes sense in PHP.

Best regards
Tim Düsterhus

<<attachment: clone_with.php>>

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to