Re: [RFC] [Discussion] Clone with
| From: | Nicolas Grekas | Date: | Thu, 08 Jun 2023 18:15:49 +0000 |
| Subject: | Re: [RFC] [Discussion] Clone with | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-120541@lists.php.net to get a copy of this message | ||
> On Tue, May 30, 2023, at 10:04 PM, Alexandru Pătrănescu wrote:
> > > On Tue, May 30, 2023, 19:39 Larry Garfield <larry@garfieldtech.com>
> > wrote:
> > >
> > >> On Mon, May 29, 2023, at 11:22 PM, Máté Kocsis wrote:
> > >> > To be honest, the current behavior seemed like the natural choice
> for
> > >> > me, and I didn't really consider to execute the __clone() method
> after
> > >> the
> > >> > clone assignments.
> > >> > Do you have a use-case in mind when you need to forward-pass
> > information
> > >> to
> > >> > __clone()?
> > >>
> > >> Not a specific one off hand. It's more a conceptual question.
> > >>
with
> > has
> > >> more contextual awareness than __clone(), so it should have "first
> > crack"
> > >> at the operation, so that if necessary it can make changes that
> > __clone()
> > >> can then respond to. The inverse doesn't make sense.
> > >>
> > >> The only reason for with to come after would be
> > >> to allow with to
> > >> "override" or "undo" something that __clone() did. Generally
> speaking,
> > if
> > >> you have to undo something you just did, you shouldn't have done it in
> > the
> > >> first place, so that's a less compelling combination.
> > >>
> > >> This one isn't a deal breaker, but we should be sure to think it
> through
> > >> as it's kinda hard to reverse later.
> > >>
> > >
> > > To me so far also it was natural to assume that __clone is first and
> only
> > > after that the rest of the operations.
> > > But with operations, be it properties assignment or
> > > even a closure,
> > would
> > > run in the context of the caller of clone and sometimes this might be
> run
> > > not from a method of the cloned class.
> > >
> > > An example:
> > > There is a class that represents persons of a fictive country/planet.
> > > Each person has many properties but has also a first name and a last
> name
> > > and there is a rule: the two names must not start with the same letter.
> > > Both names cannot be changed as they are defined readonly.
> > > Creation of new persons can be done using new for new random properties
> > or
> > > using clone to preserve existing properties. But in both cases the
> first
> > > name and last name are randomly chosen.
> > > If we want to control the last name value during clone that would be
> > > possible using the with operation but the logic to
> > > allocate a first
> > name
> > > will only happen in __clone()method.
> > >
> > > To be able to achieve this we must have __clone last, as there we have
> > the
> > > internal validations, operations and also access to private/protected
> > > members that are not accesible from where clone is being called.
> > >
> > > Regards,
> > > Alex
> >
> > I... could not understand that in the slightest. Can you show it in
> code?
> >
> >
>
> Sorry for that. Here you go:
> https://3v4l.org/JIBoI/rfc#vgit.master
> If __clone would be first, there is no way to enforce the rule that a
> person cannot have their first name starting with the same letter as last
> name.
>
I'm not sure that's what __clone should be used for.
This looks like a perfect use case for property hooks, isn't it?
On my side, I would find it unexpected that __clone is called after because
that would break cloning expectations:
Imagine you have a __clone that does some deep cloning (a much more typical
scenario for this construct),
Let's say __clone() does $this->foo = clone $this->foo;
Imagine now that you do: clone $obj with (foo: $bar)
I'd expect $obj->foo === $bar after this. But if __clone is called after,
that won't be true, and I don't see how that could be "fixed" if we swap
the order. Would you?
Nicolas