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

Reply via email to