Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:102917 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 56010 invoked from network); 19 Jul 2018 14:20:14 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Jul 2018 14:20:14 -0000 Authentication-Results: pb1.pair.com header.from=cmbecker69@gmx.de; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=cmbecker69@gmx.de; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmx.de designates 212.227.15.19 as permitted sender) X-PHP-List-Original-Sender: cmbecker69@gmx.de X-Host-Fingerprint: 212.227.15.19 mout.gmx.net Received: from [212.227.15.19] ([212.227.15.19:55633] helo=mout.gmx.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 3C/8B-37178-C1E905B5 for ; Thu, 19 Jul 2018 10:20:13 -0400 Received: from [192.168.2.102] ([87.167.201.185]) by mail.gmx.com (mrgmx002 [212.227.17.190]) with ESMTPSA (Nemesis) id 0MZTbR-1fSBq13p2T-00LFoO; Thu, 19 Jul 2018 16:20:09 +0200 To: Rowan Collins , PHP internals References: <8916EC21-D368-40F8-9ABD-CE0C04A73539@gmail.com> <1832302.prXWr4o048@vulcan> Message-ID: Date: Thu, 19 Jul 2018 16:20:12 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: de-DE Content-Transfer-Encoding: 8bit X-Provags-ID: V03:K1:Kit4UaVk59HQd7RFUH9esQq1mEMYVqluM2do4r9G9OIki4Sqse+ /z9orx9rFsevqwGTGfdDepmQ9qbul+QuOR/aKYnz2CPciaNGc5l8UD7NpaS5SUXjFP+73Ck EgVeLb86AzwJKnTMKCXaVJCUovT3OTh4mUW2up+qyKyVpxa3E9elLUdO7Pia7GK7Y4mNhlr 4RxeNSkrcNX4VS5Yu7PwA== X-UI-Out-Filterresults: notjunk:1;V01:K0:KsTkCduTPRU=:g1/HGLmNMhIPmRXVvEz7RV y0X4kizrSzDU72vq//0hIyl9jTIBoGJcIaRvkYa8lg1m5QHWCXzVk+tq3qDQ120FOGkTOM228 ilMmsHwhvdZu/IvyA+S9+JFO7kPUWJXvLVNTIyhC66Vdd+uix9RFET+ZPoQIfufwqP7qcuook 0HkuLNGRKhgzYzyDxEmjEvaq39olgN3dfZZ3uScIX9T/uNNhEVNbeT4V2Edj9TU4rjOShCCm6 9mFU0HhVQdUPk9mIbrwdpam62f2a9FzlwBucEkVsurxbWt2rBC1ONZUXuC+yHsh37R96dUWxV di09DYFrklnRmc1cWs8r12gpfYkmHPLwm/nQIr9YIVLnj3FgoySK0f1MUysASR6TCWXnDhFvB q5GkrNiCR8/OwFkeNqGpljnZQ90dCbalonZmH3vhVD4l55EPhk6v7Be98mzS8bIxdmfBJ5MzU SIuUU3NqFEyU7Lab/uPVifWncNhw0vi7ttZR7KhtE5c70twTTWGTuPwGH158PzF1w/dE+lZZe WaSTM3P6DnsRVLlVoJ+ZKmr5oBmYnvAMz4W7LjBcwYXidrlS8FcCurgcLqhyg/avfVJMzSsko CAUT8z6ZXGoUbqjXq/aUmtxc1p9SHYCRiauuiuhdBOen9RzUQ1WCHwNc+JqVnYBCYpwgNNuDS HLjimbsPN2KPygNQxk84L/dume6o4ma1CsR/1gmQNKwh+0M7iWKMXoQkNQpKhpkKlo8wgFzmX yLiR4GbdsjNehLpLCXqHQ+yGYPAmidKvZv1R8Be6ydeNp3U6k04EjpLC4qC+3Sr0Q9567EY2n WUKWgee Subject: Re: [PHP-DEV] Non-nullable properties From: cmbecker69@gmx.de ("Christoph M. Becker") On 19.07.2018 at 15:41, Rowan Collins wrote: > On 16 July 2018 at 17:09, Larry Garfield wrote: > >> class Foo { >> >> protected Bar $b; >> >> // This runs before __construct, is not inherited, and cannot >> // ever be skipped. If this method exits and any property is still >> // value-less, TypeError immediately. >> protected function __init() { >> $this->b = new Bar(); >> } >> >> public function __construct() { >> Behaves as it always has. >> } >> } >> >> That's similar to the "initialize" flag inside the constructor, but splits >> it >> off to a separate method that is devoted to just that purpose; it >> therefore >> has no parameters, ever, and if you want to initialize an object property >> based on a constructor argument then you must either make it explicitly >> nullable or initialize it to a dummy value first. > > The extra method certainly feels more "PHP-like" than an extra keyword, but > as you say, calling it automatically makes it awkward to initialise based > on any kind of input. > > A couple of variations on the theme: > > a) __init() takes the same arguments as __construct(), but is called first. > This might be rather confusing, though - we could insist on the signatures > matching, but people might be surprised that their constructor parameters > are passed to their object twice in different methods. > > b) __init() is not called automatically, but has to be called manually, > with whatever parameters you want, as the first line of __construct(). This > feels a bit weird, because no other method name causes special behaviour > when called manually. On the other hand, it allows it to be called in other > situations, such as unserialize, which by-pass the constructor. > > A compromise system which doesn't need new keywords or magic would be to > combine the current error-on-access behaviour with a check at the end of > the constructor. > > So: > > = as soon as the constructor starts, $this is available as normal > = accessing non-nullable properties of $this before initialising them would > give an error (as in the current proposal) > + when the constructor returns, the engine checks that all non-nullable > properties have been correctly initialised, and immediately throws an error > if they have not > + Serializable#unserialize() could run the same check, since it is > effectively a constructor > = ReflectionClass#newInstanceWithoutConstructor could just allow the > incomplete object, since such an object is not likely to work smoothly > anyway > > Since $this can be passed to other functions and methods by the > constructor, there is still a chance of code outside the class seeing an > incomplete object and getting errors, but the distance between cause and > effect (which is my main objection to the current proposal) is massively > reduced. It seems to me that either of these proposals would render the lazy initialization pattern outlined in the “Overloaded Properties” section[1] invalid. [1] -- Christoph M. Becker