Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:102916 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 53283 invoked from network); 19 Jul 2018 13:41:22 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Jul 2018 13:41:22 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.214.49 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 209.85.214.49 mail-it0-f49.google.com Received: from [209.85.214.49] ([209.85.214.49:35524] helo=mail-it0-f49.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id CE/2B-37178-205905B5 for ; Thu, 19 Jul 2018 09:41:22 -0400 Received: by mail-it0-f49.google.com with SMTP id q20-v6so9408348ith.0 for ; Thu, 19 Jul 2018 06:41:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=msIlTOAd5EnE1fbgnRPdGmnBzYndkSMiJxp6E/D8xok=; b=sVChU+yJCw+QiEIB/hqbsyOhu1zeyk3TkixgZdYN2eW2tui3oZPTHt0zGUHxofbXlf 72n7TFb2S+EoweqMeWbd44XuB44YZ89QoFCz4DzHoYQta5kBAwOEQOoeY9FTsUCjk7K2 ZprVE2b/zoNQ3vhIuHtSNoWkG7ebwYVn03r+MQyzlzzKvxl8juoNAug2A3gzpKrTLKGi Z3woax8Qw2rDBYgEX+ychS6ckwDU0Ql8HKEUyxz8XgWbZcxfJO4gWruLVHqbQBLjBpK+ NlQLQmQwjCeE0XbWZs3DKWcE/6l70wtPSFivhYFIxqN77Ps7xiaml7vKCi4JGp0cFWpX JOAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=msIlTOAd5EnE1fbgnRPdGmnBzYndkSMiJxp6E/D8xok=; b=WOxQC/c3f8cwlJyxu4TvYLkSspMxfXbNhX3QwOkbrz5/cEKGcZzUGC4xUv9KkdPtNk dvpxlp3jo20koietjebkdVVYNlPKObhTG1Akw1F7BxjhZ74kHsDMbVB9EPy5GXnL8hTO 4akt4i3upCuI90wGwAwnP8uZhmTnRs1+AfkOU5NkQaMeJcb56NSGvveA8/k6m5O7Tdb6 ByqxIXaGRVHSfTzdoYMeOnmPoOr4/2rluG442cL10yjwvTRDdBj+iUzDDM7mjdf3/snd jEv1B1TQ1zeyka0wEqGH8gpsFtgQ6Ih77TeIQx2L6J26LUQmMXzpNmywGQATDptswnnJ mbRQ== X-Gm-Message-State: AOUpUlETJmQpErQc1cc5K/d4xGq8e7Zge/5EVUtOEA1bytNLpGVhaprv Eqe/G6a8RGqBtTICcXr7t96YZH5s2tu/41UsORiDcfDE X-Google-Smtp-Source: AAOMgpeRyefyzqhaYDnH7ZUdhgIKGo6ckZb9epzTVXTYH5fBVM+W2SEw1F1+FLgdqCXxYkxG/mop7ryhu9AXHJQLfa8= X-Received: by 2002:a24:ce81:: with SMTP id v123-v6mr5452856itg.119.1532007679438; Thu, 19 Jul 2018 06:41:19 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a02:95a8:0:0:0:0:0 with HTTP; Thu, 19 Jul 2018 06:41:18 -0700 (PDT) In-Reply-To: <1832302.prXWr4o048@vulcan> References: <8916EC21-D368-40F8-9ABD-CE0C04A73539@gmail.com> <1832302.prXWr4o048@vulcan> Date: Thu, 19 Jul 2018 14:41:18 +0100 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="00000000000086b55905715a5578" Subject: Re: [PHP-DEV] Non-nullable properties From: rowan.collins@gmail.com (Rowan Collins) --00000000000086b55905715a5578 Content-Type: text/plain; charset="UTF-8" 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. Regards, -- Rowan Collins [IMSoP] --00000000000086b55905715a5578--