Bug #64235 [Com]: Insteadof not work for class method in 5.4.11

From: Date: Wed, 20 Feb 2013 16:22:56 +0000
Subject: Bug #64235 [Com]: Insteadof not work for class method in 5.4.11
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-177266@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=64235&edit=1

 ID:                 64235
 Comment by:         reeze@php.net
 Reported by:        imenem at inox dot ru
 Summary:            Insteadof not work for class method in 5.4.11
 Status:             Feedback
 Type:               Bug
 Package:            Scripting Engine problem
 Operating System:   Debian GNU/Linux
 PHP Version:        5.4.11
 Assigned To:        dmitry
 Block user comment: N
 Private report:     N

 New Comment:

currently using class in context of trait 'as' and 'inteadof'
didn't work most of the time (as the code below demonstrated, even after apply the patch
larucence attached). Only the use case of this bug report, it HAPPENED to work. 


To keep the BC of the problem reported, as I suggested in the previous patch we could 
mark it as deprecated in 5.4.

So forbid class in 'as' and 'insteadof' didn't break because most of them
didn't even work.

in the case of parent class insteadof usage, the REAL need is avoid trait's method overwrite
the method inherited but not refer to parent class.

there is a really easy workaround: rename the conflict method as
a new one Traits::method as _use_less or something else, 
if we really need the method from parent.


<?php

class Standalone {
	function foo() {
		echo "I shouldn't been called";
	}
}

class GrandParent {
	function foo() {
		echo "GrandParent";
	}
}

class Parent extends GrandParent {
	function foo() {
		echo "Parent";
	}	
}

trait T {
	function foo() {
		echo "Trait";
	}
}

class Child extends Parent {
	use T {
		/* as */
		Parent::foo as bar;		// Child::bar() -> undefined method
		StandAlone::foo as bar; // Child::bar() -> undefined method
		StandAlone::foo as foo; // Child::foo() -> "Trait"
		GrandParent::foo as bar; // Child::bar() -> undefined method

		/* insteadof */
		Parent::foo insteadof T; // works by accident -> "Parent"
		GrandParent::foo insteadof T; // -> "Parent" but not "Grand"
		StandAlone::foo insteadof T; // ->"Parent"
	}
}


Previous Comments:
------------------------------------------------------------------------
[2013-02-20 14:40:32] laruence@php.net

@Stefan the current patch is allow use insteadof with classes (as the reporter 
said, it used to works), 

and forbid use "as" with classes (5.4.11 will result in an unexpected FATAL 
error "undefined method", which is very confused message), the new solution is 
trigger compiler ERROR

so, for the current patch, I think it is consistent with before, no need to be 
RFCed again.

however, if we decide to forbind using both 'as' and 'insteadof' with classes, 
that definitely need a RFC

------------------------------------------------------------------------
[2013-02-20 13:20:15] gron@php.net

Hi:

The insteadof and as operators where not intended to be used with classes.
The syntax is intended to convey that the use operation is refined by specifying how to 
resolve conflicts __between__ traits.
That's the idea at least.

My solution for the initial problem presented would be to provide a method such as follows in 
the TestChildClass:
  public function method() {
    parent::method();
  }

I understand that this is not ideal, and requires you to repeat yourself.
However, it is consistent in the sense that traits are traits and not classes, and both get 
mixed up as little as possible,

However, beside the academic notion of purity, I can see that `TestParentClass::method 
insteadof TestTrait;` is useful.
[I wonder whether parent::method insteadof TestTrait; should be supported as well.]


Laruence's example with TestParentClass::method as methodParent; is however
problematic. 
Traits are not supposed to conflict with classes, but with traits. So, allowing the 
introduction of aliases for method of the super class seems to me as something that is 
problematic, because it mixes up the concepts.

If you need an alias for the method of a parent class, the classic way would be:

public function foo() {
  parent::bar();
}

No?


Well, that's my point of view.


So, from a practical point of view, referring to the parent (and only the direct parent) class 
in insteadof might be a useful/acceptable feature.
The use in conjunction with as seems to be something I would advocate against.
In either way, beside bugs that made this possible in the first place, I would consider both 
ideas as new features that need to be documented/discussed.

I thought that we had a test that only the traits listed in the use clause can be used
for 
the as/insteadof operators, but that's either broken or not there, or
a bug that was fixed 
in 5.4.11 as the original report suggests.
Therefore, from my perspective, 5.4.11 shows the behavior that's intended by the spec/RFC.

Best regards
Stefan

------------------------------------------------------------------------
[2013-02-20 08:22:01] laruence@php.net

reeze, *before* doesn't always means *RIGHT*.

------------------------------------------------------------------------
[2013-02-20 08:16:52] reeze@php.net

@laurence  the code you paste above works the same as before:
http://3v4l.org/UpMCW#v5411 that didn't break

After read some doc I assume class is not suitable in context of 'insteadof', 
so let's wait for Stefan or more discussion :)

------------------------------------------------------------------------
[2013-02-20 08:12:40] laruence@php.net

form the context,  insteadof works at class make sense.

reeze, whatever the RFC is, your fix simply skip check for classes at all, which 
will make the test script I paste result in "FATAL ERROR, undefined method", that 
is not acceptable.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=64235


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=64235&edit=1


Thread (21 messages)

« previous php.bugs (#177266) next »