Pass source object to clone like __clone($origThis)

  111791
September 2, 2020 18:41 vorismi3@fel.cvut.cz (=?UTF-8?Q?Michael_Vo=C5=99=C3=AD=C5=A1ek_-_=C4=8CVUT_FEL?=)
Hi, please look at
https://stackoverflow.com/questions/63675888/get-original-source-instance-in-clone


do you have anything against updating PHP to pass "instance before
cloned" to any __clone call from php? 

no BC - user may accept this extra argument or declare function
__clone() without any param like now 

With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem,

Michael Voříšek
  111793
September 2, 2020 19:10 david.proweb@gmail.com (David Rodrigues)
I understand... seems that `$this` is very confusing inside `__clone()`:
when writing, it writes to the clone, when reading it reads from original.

Seems valid a new optional parameter definition with the original source.



Atenciosamente,
David Rodrigues


Em qua., 2 de set. de 2020 às 15:41, Michael Voříšek - ČVUT FEL <
vorismi3@fel.cvut.cz> escreveu:

> Hi, please look at > > https://stackoverflow.com/questions/63675888/get-original-source-instance-in-clone > > > do you have anything against updating PHP to pass "instance before > cloned" to any __clone call from php? > > no BC - user may accept this extra argument or declare function > __clone() without any param like now > > With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem, > > Michael Voříšek
  111818
September 3, 2020 14:21 pollita@php.net (Sara Golemon)
On Wed, Sep 2, 2020 at 2:11 PM David Rodrigues proweb@gmail.com>
wrote:

> I understand... seems that `$this` is very confusing inside `__clone()`: > when writing, it writes to the clone, when reading it reads from original. > > That's not an accurate description of what happens today.
$newObj = clone $oldObj; // 1. Engine creates a new instance of get_class($oldObj), without calling the constructor // 2. Engine copies all properties from the old object to the new object // 3. Engine invokes $newObj->__clone() public function __clone() { // Userspace object handles any property specific re-initialization required. // $this always refers to the new object here. } The question Niki asked is appropriate; What would one want to do to $oldObj here? If the goal is to read from the old object, then you have that already. The new object is a perfect copy, so read from that. If the goal is to write to the old object, then justify why you need to do so, because it's not a clone operation at that point. -Sara
  111825
September 3, 2020 15:39 david.proweb@gmail.com (David Rodrigues)
Now I rethinked about what I said. Really, maybe clone is not the best
option. So maybe we can just use a method that will clone and will have
access to both informations. But I don't know if it solves the original
message.

public function getUserCopy() {
    $userCopy = clone $this;
    $this->copies[] = $userCopy;

    return $userCopy;
}

Considering it, we have access to both now, with "write to source" support
with no additional feature need.

Em qui, 3 de set de 2020 11:21, Sara Golemon <pollita@php.net> escreveu:

> On Wed, Sep 2, 2020 at 2:11 PM David Rodrigues proweb@gmail.com> > wrote: > >> I understand... seems that `$this` is very confusing inside `__clone()`: >> when writing, it writes to the clone, when reading it reads from original. >> >> > That's not an accurate description of what happens today. > > $newObj = clone $oldObj; > // 1. Engine creates a new instance of get_class($oldObj), without calling > the constructor > // 2. Engine copies all properties from the old object to the new object > // 3. Engine invokes $newObj->__clone() > public function __clone() { > // Userspace object handles any property specific re-initialization > required. > // $this always refers to the new object here. > } > > The question Niki asked is appropriate; What would one want to do to > $oldObj here? > If the goal is to read from the old object, then you have that already. > The new object is a perfect copy, so read from that. > If the goal is to write to the old object, then justify why you need to do > so, because it's not a clone operation at that point. > > -Sara >
  111827
September 3, 2020 16:00 pollita@php.net (Sara Golemon)
On Thu, Sep 3, 2020 at 10:40 AM David Rodrigues proweb@gmail.com>
wrote:

> Now I rethinked about what I said. Really, maybe clone is not the best > option. So maybe we can just use a method that will clone and will have > access to both informations. But I don't know if it solves the original > message. > > public function getUserCopy() { > $userCopy = clone $this; > $this->copies[] = $userCopy; > > return $userCopy; > } > > If your goal is to track copies, then a static makes much more sense.
class AllKnowing { private static $copies = []; public function __construct(...) { self::$copies[] = $this; .... } public function __clone() { self::$copies[] = $this; } } -Sara
  111828
September 3, 2020 16:03 david.proweb@gmail.com (David Rodrigues)
It was just an example to avoid modify how clone works, using existing
features. :)

Em qui, 3 de set de 2020 13:00, Sara Golemon <pollita@php.net> escreveu:

> On Thu, Sep 3, 2020 at 10:40 AM David Rodrigues proweb@gmail.com> > wrote: > >> Now I rethinked about what I said. Really, maybe clone is not the best >> option. So maybe we can just use a method that will clone and will have >> access to both informations. But I don't know if it solves the original >> message. >> >> public function getUserCopy() { >> $userCopy = clone $this; >> $this->copies[] = $userCopy; >> >> return $userCopy; >> } >> >> > If your goal is to track copies, then a static makes much more sense. > > class AllKnowing { > private static $copies = []; > > public function __construct(...) { > self::$copies[] = $this; > .... > } > > public function __clone() { > self::$copies[] = $this; > } > } > > -Sara >
  111830
September 3, 2020 16:06 pollita@php.net (Sara Golemon)
On Thu, Sep 3, 2020 at 11:03 AM David Rodrigues proweb@gmail.com>
wrote:

> It was just an example to avoid modify how clone works, using existing > features. :)
>
Right, but the question remains "Why would we want the original object during a clone operation?". No legitimate example of that has been provided yet. -Sara
  111832
September 3, 2020 16:36 vorismi3@fel.cvut.cz (=?UTF-8?Q?Michael_Vo=C5=99=C3=AD=C5=A1ek_-_=C4=8CVUT_FEL?=)
The goal is to be able to access the original object and it's id/hash. 

Usecases: 

- something is associated with the object using the object id/hash and
it needs to be cloned as well 

we need the original object to obtain it's id/hash for spl_object_id and
spl_object_hash methods 

- bounded Closures ar associated with the original object and they needs
to be rebound to the cloned object 

example: 

public function __clone(self $origThis)
{
    if ((new \ReflectionFunction($this->fx))->getClosureThis() ===
$origThis) {
        $this->fx = \Closure::bind($this->fx, $this);
    }
} 

Modification of php is simple: 

https://github.com/php/php-src/pull/6063/files#diff-beea8c5a8ceb318220b34b73e4ecfc98R252


we simply pass the old object as 1 parameter. I belive, passing old
object have positives and no performance nor compatibility impact. All
other current solutions require an extra property and a lot of code, as
assigning in constructor is not enough (due serialization etc.), or it
is even impossible, if object was created using reflection without
constructor. 

With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem,

Michael Voříšek

On 3 Sep 2020 18:00, Sara Golemon wrote:

> On Thu, Sep 3, 2020 at 10:40 AM David Rodrigues proweb@gmail.com> > wrote: > >> Now I rethinked about what I said. Really, maybe clone is not the best >> option. So maybe we can just use a method that will clone and will have >> access to both informations. But I don't know if it solves the original >> message. >> >> public function getUserCopy() { >> $userCopy = clone $this; >> $this->copies[] = $userCopy; >> >> return $userCopy; >> } > If your goal is to track copies, then a static makes much more sense. > > class AllKnowing { > private static $copies = []; > > public function __construct(...) { > self::$copies[] = $this; > .... > } > > public function __clone() { > self::$copies[] = $this; > } > } > > -Sara
  111833
September 3, 2020 17:43 david.proweb@gmail.com (David Rodrigues)
Just to I know, it can't be done by an intermediary method like my previous
example? Why are the limitations to that?

About PR, could you provide some additional tests?

Thanks!

Em qui, 3 de set de 2020 13:37, Michael Voříšek - ČVUT FEL <
vorismi3@fel.cvut.cz> escreveu:

> The goal is to be able to access the original object and it's id/hash. > > Usecases: > > - something is associated with the object using the object id/hash and > it needs to be cloned as well > > we need the original object to obtain it's id/hash for spl_object_id and > spl_object_hash methods > > - bounded Closures ar associated with the original object and they needs > to be rebound to the cloned object > > example: > > public function __clone(self $origThis) > { > if ((new \ReflectionFunction($this->fx))->getClosureThis() === > $origThis) { > $this->fx = \Closure::bind($this->fx, $this); > } > } > > Modification of php is simple: > > > https://github.com/php/php-src/pull/6063/files#diff-beea8c5a8ceb318220b34b73e4ecfc98R252 > > > we simply pass the old object as 1 parameter. I belive, passing old > object have positives and no performance nor compatibility impact. All > other current solutions require an extra property and a lot of code, as > assigning in constructor is not enough (due serialization etc.), or it > is even impossible, if object was created using reflection without > constructor. > > With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem, > > Michael Voříšek > > On 3 Sep 2020 18:00, Sara Golemon wrote: > > > On Thu, Sep 3, 2020 at 10:40 AM David Rodrigues proweb@gmail.com> > > wrote: > > > >> Now I rethinked about what I said. Really, maybe clone is not the best > >> option. So maybe we can just use a method that will clone and will have > >> access to both informations. But I don't know if it solves the original > >> message. > >> > >> public function getUserCopy() { > >> $userCopy = clone $this; > >> $this->copies[] = $userCopy; > >> > >> return $userCopy; > >> } > > If your goal is to track copies, then a static makes much more sense. > > > > class AllKnowing { > > private static $copies = []; > > > > public function __construct(...) { > > self::$copies[] = $this; > > .... > > } > > > > public function __clone() { > > self::$copies[] = $this; > > } > > } > > > > -Sara
  111811
September 3, 2020 11:06 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Sep 2, 2020 at 8:42 PM Michael Voříšek - ČVUT FEL <
vorismi3@fel.cvut.cz> wrote:

> Hi, please look at > > https://stackoverflow.com/questions/63675888/get-original-source-instance-in-clone > > > do you have anything against updating PHP to pass "instance before > cloned" to any __clone call from php? > > no BC - user may accept this extra argument or declare function > __clone() without any param like now >
Could you please provide some more information on what the intended use-case is? I'm not opposed to this change, but I also don't understand why it is needed. Regards, Nikita
  111812
September 3, 2020 11:48 mail@pmmaga.net (=?UTF-8?Q?Pedro_Magalh=C3=A3es?=)
On Wed, Sep 2, 2020 at 7:41 PM Michael Voříšek - ČVUT FEL <
vorismi3@fel.cvut.cz> wrote:

> do you have anything against updating PHP to pass "instance before > cloned" to any __clone call from php? >
Yes, I think that allowing the original object to be modified by a cloning operation could be the cause for a lot of confusion. If we had a proper way to make it read-only I wouldn't mind, but as is, it doesn't sound like a good idea.
  111817
September 3, 2020 13:41 david.proweb@gmail.com (David Rodrigues)
I don't see problem to allow modify the original object, once that you are
doing it by using a new argument, and not the $this itself.

Em qui, 3 de set de 2020 08:49, Pedro Magalhães <mail@pmmaga.net> escreveu:

> On Wed, Sep 2, 2020 at 7:41 PM Michael Voříšek - ČVUT FEL < > vorismi3@fel.cvut.cz> wrote: > > > do you have anything against updating PHP to pass "instance before > > cloned" to any __clone call from php? > > > > Yes, I think that allowing the original object to be modified by a cloning > operation could be the cause for a lot of confusion. If we had a proper way > to make it read-only I wouldn't mind, but as is, it doesn't sound like a > good idea. >