Re: [RFC] Object Initializer
| From: | Marco Pivetta | Date: | Sat, 14 Sep 2019 08:50:04 +0000 |
| Subject: | Re: [RFC] Object Initializer | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-107086@lists.php.net to get a copy of this message | ||
On Sat, Sep 14, 2019 at 10:47 AM Mike Schinkel <mike@newclarity.net> wrote:
> > On Sep 13, 2019, at 3:18 AM, Rasmus Schultz <rasmus@mindplay.dk <mailto:
> rasmus@mindplay.dk>> wrote:
> >
> > Assuming the fields of this entity are required, you would probably
> prefer
> > to add a constructor - but then property initializers aren't really
> useful
> > anymore.
>
> I think this is a false dichotomy; I can see benefit to having
> initializers in addition to constructors, even for the same classes.
>
> However, Object Initializers might be best when paired with a new magic
> method which let us call __init(), and a required modifier for properties.
>
> Using your Customer example, the __init() would be automatically called
> after __construct():
>
> class Customer
> {
> private string $name = '';
> required protected ?string $email = null;
>
> public function __construct(string $name, ?string $email = null)
> {
> $this->name = $name;
> $this->email = $email;
> }
>
> public function __init()
> {
> $this->name = ucwords($this->name);
> $this->email = sanitize_email($this->email);
> }
> }
>
> With __init() a developer could separate capturing construct parameters
> from initializing required fields, but the required modifier would allow
> developers to indicate which properties should be required.
>
> And it might even make sense to throw an error if an object initializer
> does not have an __init() method. Requiring __init() would ensure that
> classes not designed to work with initializers would never be initialized
> without required fields set.
>
> When creating an object using object initialization I think it should just
> bypass and only call __init(). PHP could generate an error if any required
> fields are not set.
>
> $customer = new Customer{
> name => 'mike schinkel',
> email => 'mike@newclarity.net
> <mailto:mike@newclarity.net>'
> }
> echo $customer->name; // Prints "Mike Schinkel"
>
> Actually, a required modifier would not be required to implement object
> initializers (no pun intended) but it would enable IDEs, PHP and other
> tools validate whether or not a required fields has been set.
>
> As an aside, it would be interesting if there were a __validate() magic
> method although it might harm performance too much. OTOH, it should not
> harm performance unless you actually use it:
>
> public function __validate(string $field):bool
> {
> switch ($field) {
> case 'name':
> return !empty( $this->name ) && strlen($this->name) >= 3;
> case 'email':
> return validate_email($this->email);
> }
> return true;
> }
>
> > a desire to use this language feature will drive architecture. ... this
> will
> > provide the wrong kind of motivation to make what are, effectively,
> > architectural decisions.
>
> The reason I badly want object initializers is to empower architectures
> that currently are not possible in PHP. So I see this as a positive.
>
> I see architectures used in other languages that reduce tedium and enhance
> reusability that we cannot implement in PHP because of lack of an object
> initializer.
>
> But maybe I do not realize what you are seeing? Can you please elaborate
> on the architectures you fear will emerge, ideally with examples and
> reasons why they should be avoided?
>
>
> -Mike
>
>
Hey Mike,
lazy initialisation is already possible in userland: adding more magic to
the language for a use-case that is already implemented seems problematic
to me.
Marco Pivetta
http://twitter.com/Ocramius
http://ocramius.github.com/