Re: Weak Closures
| From: | Christoph M. Becker | Date: | Sat, 22 Jan 2022 15:30:22 +0000 |
| Subject: | Re: Weak Closures | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-116906@lists.php.net to get a copy of this message | ||
On 21.01.2022 at 11:31, Dominic Grostate wrote:
> I'd like to express my interest in a possible feature concerning weak
> references. Currently closures created within a class appear to
> contain a reference to the object that created it. This is of course
> necessary in order for the closure to retain the necessary scope.
> However I would like to suggest we have the option for closure to
> weakly reference this object so that when the object is garbage
> collected, the closure too may be rendered null or invalid
> (inspectable).
>
> Consider the following example:
> https://gist.github.com/orolyn/7651e4127759aad1736547490baa1394
>
> The idea here is that without unset($sample) the loop would run
> forever, because there is a reference to the callback from the object,
> and in turn there is a reference to the object from the main stack.
> With the unset($sample), the idea is that before the callback is even
> called, the reference to the object is destroyed thusly so is the
> reference to callback, and since the callback is only referenced now
> in a WeakMap, the callback will finally be gone.
>
> In reality it appears there is a circular reference between the object
> and the callback. I don't know if this is a bug or not, because from
> what I can find PHP was fixed a long time ago to resolve circular
> references.
>
> However if this is intentional, I would like the option to make the
> closure weak for example:
>
> $c = WeakClosure::fromCallable(function () {});
> $c = Closure::fromCallable(function () {}, true);
>
> Please let me know your thoughts, because maybe there is a way of
> achieving this with PHP as is.
If you trigger the garbage collector manually (i.e. call
gc_collect_cycles() after unset($callback)), the loop terminates right
away. I'm not sure why it doesn't without manually triggering the GC.
Christoph