Re: OBJECT_OPERATOR vs. DOUBLE_COLON
| From: | Rowan Collins | Date: | Wed, 05 Jul 2017 10:24:39 +0000 |
| Subject: | Re: OBJECT_OPERATOR vs. DOUBLE_COLON | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-99757@lists.php.net to get a copy of this message | ||
On 5 July 2017 08:08:48 BST, Sebastian Bergmann <sebastian@php.net> wrote:
>Is it intentional that the DOUBLE_COLON operator can be used on a
>variable that contains a reference to an object?
>
><?php
>class C
>{
> public function m()
> {
> print '*';
> }
>}
>
>$c = new C;
>$c::m();
>
>Until yesterday I thought that only the OBJECT_OPERATOR (->) can be
>used
>on a variable that contains an object. https://3v4l.org/59Xap
>proved me
>
>wrong.
>
>As the deprecation / strict standards notices suggest, though, $c::m()
>does not invoke the method m() on the object referenced by $c. It
>invokes the method statically on C (the class of the object referenced
>by $c): https://3v4l.org/19taB
>
>I think that using :: on a variable that contains an object should not
>"fall back" to a static access on the object's class. Instead the
>runtime should error out.
>
>What do you think?
Hi Sebastian,
Firstly, I'm not sure where you got the names you've put in ALL_CAPS from, but
they're not the official names of the operators anywhere I've seen. The double-colon is
technically the "Scope Resolution Operator", or internally T_PAAMAYIM_NEKUDOTAYIM (which
does mean double-colon). It's described in the manual here: http://php.net/manual/en/language.oop5.paamayim-nekudotayim.php
I too was slightly surprised when I first learned it could be used against an instance as well as a
class name, but there are situations where this is useful. For instance, accessing a class constant
associated to some object when interacting with that object, e.g.
"$foo->doThing($foo::MODE_X)".
If we could only use it on class names, we'd have to use the "::class" operator to go
from one to the other, like "$foo::class::MODE_X"; or perhaps we'd change that
operator too and write "$foo->class::MODE_X". That's not awful, I suppose, but it
doesn't feel like a big gain.
We'd also need to consider the consistency of "parent::", which resolves the scope
but *doesn't* force a static access, because you need to be able to call an inherited
non-static member.
Like most established languages and frameworks, we don't have the luxury of going back and
changing old design decisions, we have to look at if and how we should evolve from where we are now.
I think removing this behaviour, even if we found something nicer to replace legitimate uses with,
would be a huge compatibility break, for very little gain, so is unlikely to get anywhere.
Regards,
--
Rowan Collins
[IMSoP]