Hi Alexandru, hi Shinji > Hey, sorry to bump here on this topic. > > My assumption was that the use of `->` in initializers would bear the same > limitations as using `new`. > That would mean it would not be supported for > - class constant initializers > - instance property initializers > - static property initializers > > For `new` clarifications are here: > https://wiki.php.net/rfc/new_in_initializers#unsupported_positions > > My assumption is that `->` would only work for: > - static variable initializers > - global constant initializers > - parameter default values > - attribute arguments > > The examples shared by Shinji are for class constant initializers in class C > and I'm guessing it would not work. > If that's the case, I think we should clarify this in the RFC as well.
Thank you for bringing this to my attention. I have missed the case where, through constants, side-effects could be triggered in contexts where they shouldn't. class A { public function __get($name) {} } const A = new A(); class B { public $c = A->c; } I was under the incorrect impression that because (new A)->b is disallowed in property initializers __get could never be triggered in this context either but since the LHS of -> can be a constant containing another object this is indeed possible. The problem is described in the new in initializer RFC [1] you linked. There is currently no appropriate place where evaluation of the expression could happen without potential side-effects in places where we don't want them, like unserialize. Unfortunately, while thinking about this case I also discovered another issue. class A { public $b = 'b'; } const A = new A; class C { public $b = A->b; } var_dump(new C()); $a = A; $a->b = 'b2'; var_dump(new C()); Even without __get the property of an object referenced in the LHS of the -> operator can change. The engine evaluates the default property values once for the entire class and then copies the result whenever a new instance of that class gets created. That means further instances will use the out-dated property default value from when the first instance was created. Similarly, function default parameters get cached between calls. We could evaluate the constant expression for each object instantiation or function call but degrading performance for an edge case doesn't seem worth it. Since the primary motivation of this RFC is to allow fetching the name and value properties of enums I'm inclined to forbid using -> on anything but enums. That would circumvent the issue since enums can't contain user-defined properties nor the magic __get method, and name/value are readonly. I'll take a few days to think about the options, and will update the RFC and inform the mailing list about the decision I have made. Let me know if you have any more thoughts. Ilija [1] https://wiki.php.net/rfc/new_in_initializers#unsupported_positions -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php