---------- Forwarded message ---------
From: Robert Landers <landers.rob...@gmail.com>
Date: Sat, Feb 24, 2024 at 9:20 AM
Subject: History of traits + inheritance
To: internals <internals@lists.php.net>


I'm asking for a history lesson if anyone knows, as I couldn't find
any relevant information in externals and it appears to have been this
way for awhile, with a minor exception, which is the part I'm curious
about.

Consider the following code:

abstract class A {
    abstract protected function test();
}

class C extends A {
    protected function test()
    {
        return 'C';
    }
}

class D extends A {
    public function prnt(A $a) {
        echo $a->test();
    }

    protected function test() {
        return 'D';
    }
}

$d = new D;
$c = new C;

$d->prnt($d);
$d->prnt($c);

This behaves exactly how you'd expect it to behave "DC" is printed on
the screen.

However, if we add a trait:

trait E {
    protected function test() {
        return 'E';
    }
}

and implement it:

class B extends A {
    use E;
}

$d->prnt($b);

We get the following fatal error:

Call to protected method B::test() from scope D

Except that in 5.4.7 - 5.4.10, the "expected" output is given:

DCE

To me, this breaks the whole idea usually given that "traits are
fancy, compiler assisted copy-paste" since clearly it gives an error
when trying to use it like that. However, I'm mostly curious as to
what happened in 5.4.7 that "fixed" it and then was reverted after
5.4.10. There's nothing about it in the release notes for 5.4.11, and
nothing about it in externals (that I could dig up).

Another thing I'm curious about: is this intentional behavior or a bug
that probably won't be fixed (or would only be fixed via an RFC)?

Robert Landers
Software Engineer
Utrecht NL

PS. bumping this because it didn't show up on externals so I can only
assume something didn't work.

Reply via email to