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

Reply via email to