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 missingsomething, 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 commoncase 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