Hi
On 3/6/25 23:05, Rob Landers wrote:
Closure::fromCallable('Outer::Inner::method');
You end up with:
object(Closure)#1 (1) {
["function"]=>
string(20) "Outer::Inner::method"
}
Okay, does calling the closure work and correctly call the method
on the inner class? The question was intended to make sure that the implementation for callables uses the correct ::
to split. Here's another one that might be interesting:
Closure::fromCallable(["Outer::Inner", "method"]);
Closure::fromCallable(["Outer", "Inner::method"]);
constant('Outer::Inner');
This returns:
string(12) "Outer::Inner"
Okay, so this behaves as a constant containing the class name. I assume it's with the full namespace if the outer class is namespaced? I'm not sure if I want this to work like this (i.e. whether this should be an error).
$inner = 'Inner';
Outer::{$inner};
This does nothing (but resolves to "Outer::Inner")
It's consistent with constant()
and that's good.
… and any other meta-programming functionality working on class
constants or static methods.
Also, what will happen for:
class P {
class Inner { }
}
class C extends P {
const Inner = 'x';
}
(and vice versa)
This is a really good one. If for no other reason than I did a really poor job of explaining resolution(?) in the RFC.
P::Inner
belongs to
P
, not to
C
, so you can do
new C::Inner()
and it will resolve to
P::Inner()
:
I don't think the RFC explains “resolution” at all. That's why I'm asking with those specific “edge-casey” examples, so that the RFC explicitly spells out the behavior. This is not something that should be “implementation defined”, but something where an explicit design decision has been made.
I also don't understand why new C::Inner()
(w|sh)ould resolve to P::Inner()
. I think my expectation of the code snippet above would be that it is an error.
Likewise, LSP being ignored for inner classes raises an interesting question about the behavior of:
class P {
class Inner {
public function __construct(public string $foo) { }
}
public static function create() {
return new static::Inner('x');
}
}
class C extends P {
class Inner {
public function __construct(public int $bar) { }
}
}
What happens if I call C::create()
? This should also be specified in the RFC (and tested with a .phpt test).
As with other static things in PHP, you can do some really strange things like this. This is similar to how you can redefine static constants in subclasses.
We should remove the number of strange things, not add to them.
Best regards
Tim Düsterhus