On 19.07.2018 at 15:41, Rowan Collins wrote: > On 16 July 2018 at 17:09, Larry Garfield <la...@garfieldtech.com> 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] <https://wiki.php.net/rfc/typed_properties_v2#overloaded_properties> -- Christoph M. Becker -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php