Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:67593 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 18498 invoked from network); 30 May 2013 11:53:47 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 May 2013 11:53:47 -0000 Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.128.182 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.128.182 mail-ve0-f182.google.com Received: from [209.85.128.182] ([209.85.128.182:64194] helo=mail-ve0-f182.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 5C/34-15159-ACD37A15 for ; Thu, 30 May 2013 07:53:47 -0400 Received: by mail-ve0-f182.google.com with SMTP id ox1so86957veb.13 for ; Thu, 30 May 2013 04:53:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=TVqZZXRipH5Wt37LfS2ALoQllTOrXhy2JW3O56GCoLk=; b=UlhACPXC97k5gSxGCbykseqhby3CPgoCIp3cDVMVPvtqNffJGa+MkuqRFvbyKWNE3k aG1aZuJELFj3wsOc0nm8suKAoIODoprOrbpSXgG6O+1ZymJKqhASS6OwPMaHd0cOUM+0 7rJhFuRejl/FtXpm7oWU6zzWlRmLgJ/bPL6HTKC+GDqNiY0d9jLzhO5ZJs1XngQDMi02 ZqHu2N1fIZ5GjDO5QFJkdsC6jGSL7rE1dyECfH2GlJWOwFgKKxDNK7pxAbI0MZnq9rlx fZMktkiWfoqTfg9dfunyHl68n/wQR6mG3WPy1Vq1YdTlayMV2QKsDVS+latC3v7Xo6xn s/Yw== MIME-Version: 1.0 X-Received: by 10.52.186.233 with SMTP id fn9mr4454352vdc.44.1369914823558; Thu, 30 May 2013 04:53:43 -0700 (PDT) Received: by 10.58.217.197 with HTTP; Thu, 30 May 2013 04:53:43 -0700 (PDT) In-Reply-To: <6b642a96e673c29dbaf2f239be15f7f6.squirrel@www.l-i-e.com> References: <6b642a96e673c29dbaf2f239be15f7f6.squirrel@www.l-i-e.com> Date: Thu, 30 May 2013 07:53:43 -0400 Message-ID: To: Richard Lynch Cc: "internals@lists.php.net" Content-Type: multipart/alternative; boundary=bcaec547c9ef6e4ae504ddee260c Subject: Re: [PHP-DEV] Cannot call constructor From: ircmaxell@gmail.com (Anthony Ferrara) --bcaec547c9ef6e4ae504ddee260c Content-Type: text/plain; charset=ISO-8859-1 Richard et al, On Thu, May 23, 2013 at 5:24 PM, Richard Lynch 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 --bcaec547c9ef6e4ae504ddee260c--