> > I've opened voting on https://wiki.php.net/rfc/new_in_initializers. Voting >> > will close on 2021-07-14. >> > >> > Note that relative to the original RFC, new support is limited to >> parameter >> > default values, attribute arguments, static variable initializers and >> > global constant initializers, and not supported in property initializers >> > and class constant initializers. The discussion thread >> > https://externals.io/message/113347 has some extensive information on >> how >> > we got here. >> > >> >> I voted yes and I'm happy this will come to PHP. >> >> I realized I still have one concern that I want to share here, related to >> attributes: >> The RFC breaks the possibility to parse the arguments of an attribute in a >> generic and safe way. >> What I mean is that right now, attributes can be inspected while the >> corresponding classes are not installed, due eg to a missing optional >> dependency. >> > > This is not 100% correct, you can have an attribte #[Foo(Foo::class)] and > then calling ReflectionAttribute::getArguments would also require to > resolve the type Foo. So this is not different than what could happen right > now already. >
Right. Yet this can be easily worked around by using a string literal, so at least this issue can be avoided with a CS fixer when it matters. What you can do is use `ReflectionAttribute::getName()` to filter the > attributes you want to work on and only then call getArguments(). > Yes, my comment is about nested instances, not the root ones. #[Any(new Foo, new Bar)] <= Foo and Bar classes have to be defined, but this should be inspectable without instantiation, like root attributes. > This behavior is what makes attributes truly declarative: one can ignore >> what they don't care about. Extra semantics can be carried out by classes >> without making the related attributes a mandatory dependency. >> >> I think there is a way to preserve this behavior and that we should look >> for it. >> >> If I may propose one: we might add a new >> ReflectionAttribute::getUninitializedArguments() method, that would return >> the same as ReflectionAttribute::getArguments(), except that it would put >> a >> ReflectionAttribute (or similar) instance in place of objects in the data >> structure. As a corollary, we might also want to enforce that only child >> classes of the Attribute class can be nested inside another Attribute (at >> least if we want to reuse ReflectionAttribute as a placeholder.) >> > > A function like this could return all arguments that are not AST Nodes but > "literals" (instances of scalar / array types). > Foo::class or new Foo() are both AST Node types that are resolved the same > way in `getArguments`. > I guess so, but I'm not sure to get the exact point you want to make here :)