Richard et al,

On Thu, May 23, 2013 at 5:24 PM, Richard Lynch <c...@l-i-e.com> wrote:

> Consider this common scenario:
>
> I use some OOP library, that is a "black box" and I like it that way.
>
> As part of the integration, I need to extend one of the library's
> classes:
>

The problem with this entire thread (I've been thinking about this for a
while) is that it's setup from the very beginning with a failed assertion.
You want to treat a library as a black box. Great! However, you also want
to extend one of the library's classes. That's not ok. Because you cannot
ever treat inheritance as a black box. It goes against just about every
principle out there. And it's provably not possible to do.

Treating it like a black box will cause LSP violations (which PHP is so
keen on enforcing). Why? Because if you treat the parent as a black-box,
you can't guarantee that the pre-conditions, post-conditions
and invariants are not enforced (which LSP requires). So without looking at
the parent, you can't have a child that adheres to LSP.

But let's get less "rule" and more practical. Imagine the parent has no
constructor. So you, in future hindsight, decide to do this:

if (method_exists(get_parent_class(), '__construct')) {
    call_user_func_array(array(get_parent_class(), '__construct'),
func_get_args());
}

Now, what happens if the parent constructor now takes a parameter by
reference? The reference will be lost. The conceptual implementation is now
gone. Not to mention that the parameters may (and will likely) be different
from what you were expecting.

So basically, we can't ever develop completely in a black box. So if the
parent has a constructor, we need to call it (or not). But the point is,
it's never a conditional in the code. It requires you to look at, and make
a decision.

So that brings us to the case when you override a class that doesn't have a
constructor, which then gets one later on down the road. This is really
just the same as before and boils down to: 1. Test your code, as a test
should catch that. 2. Don't blindly update and expect code to work. 3. Even
if you did have a conditional, you're likely to get the arguments wrong (or
worse)...

So realistically, while I can see the appeal to having the ability to
always call parent::__construct(), I think it's actually a red-herring to
the actual problem. And it's not really necessary in the first place. In
fact, using it is likely to be a source of *more* bugs, as the object still
won't be initialized properly (but you think it is)...

My $0.02 at least,

Anthony

Reply via email to