On 29/03/2024 18:14, Robert Landers wrote:
When generating proxies for existing types, you often need to share
some state between the proxies. To do that, you put static
methods/properties on the proxy class and hope to the PHP Gods that
nobody will ever accidentally name something in their concrete class
with the name you chose for things. To help with that, you create some
kind of insane prefix.


Separating static and non-static methods wouldn't solve this - the concrete class could equally add a static method with the same name but a different signature, and your generated proxy would fail to compile.

In fact, exactly the same thing happens with instance methods in testing libraries: test doubles have a mixture of methods for configuring mock / spy behaviour, and methods mimicking or forwarding calls to the real interface / class. Those names could collide, and require awkward workarounds.

In a statically typed language, a concrete class can have two methods with the same name, but different static types, e.g. when explicitly implementing interfaces. In a "duck typing" system like PHP's, that's much trickier, because a call to $foo->bar() doesn't have a natural way to choose which "bar" is meant.


I'd much rather see static and non-static methods being able to
have the same name

Allowing this would lead to ambiguous calls, because as others have pointed out, :: doesn't always denote a static call. Consider this code:

class Test {
  public function test() { echo 'instance test'; }
  public static function test() { echo 'static test'; }
}

class Test2 extends Test {
  public function runTest() { parent::test(); }
}

(new Test2)->runTest();

Currently, this can call either of the test() methods if you comment the other out: https://3v4l.org/5HlPE https://3v4l.org/LBALm

If both are defined, which should it call? And if you wanted the other, how would you specify that? We would need some new syntax to remove the ambiguity.


Regards,

--
Rowan Tommins
[IMSoP]

Reply via email to