On 14/03/2023 21:23, Ilija Tovilo wrote:
One thing to note is that, as I've learned recently, anonymous classes
can actually be instantiated at a later point with some tricks.

https://3v4l.org/2OcmP


Huh, that's freaky... I guess this is all a reminder that these really are anonymous *classes*, not anonymous *instances* - at some point, a class entry needs to be generated.

I guess you'd have to generate a new class entry every time the "new class" line was run, and inject the extra values into that.


If it was limited to capturing scalars and arrays, you could treat it as a kind of macro expansion, i.e. this ...

$example = new class {
    public $inner = $^outer;
}

... could be a sort of sugar for:

eval(
    sprintf(
        'return new class {
            public $inner = %s;
        };',
        var_export($outer, true)
    )
);

Which is valid code, if not particularly efficient: https://3v4l.org/sQaUS

That doesn't allow for normal object semantics, though, so is probably a non-starter.


This could also prove technically challenging. Currently, property
defaults are constant ASTs and unique per class (not object).


As I understand it, the main reason object properties weren't included in the "new in initializers" RFC was the problem of when side effects would occur: https://wiki.php.net/rfc/new_in_initializers#unsupported_positions That's not an issue here, because we're not *creating* an object, we're "just" resolving the $^outer token to an existing zval, and storing it in the default property table.

It might actually be easier to *only* allow capture into property initialisers:

1. Create a new class entry without any property default (or clone a pre-compiled base)
2. Add the captured values to the default property table
3. Create an instance, run its constructor, etc, as currently

Or even:

1. Use the existing logic to create an anonymous class entry ignoring the capturing syntax 2. Create an instance, initialise normal defaults, but don't run the constructor yet
3. Push the captured values directly into the *instance* properties
4. Run the constructor


I'm probably in way over my head here, so I should probably stop here, in the hope that it will inspire someone more knowledgeable to come up with something workable, because I'd really love for anonymous classes to be more flexible than they are.

Regards,

--
Rowan Tommins
[IMSoP]

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

Reply via email to