@@ -7,7 +7,30 @@ final class Reaper
7
7
/** @var \WeakMap<object,list<self>> */
8
8
private static \WeakMap $ dd ;
9
9
10
- private function __construct (private readonly \Closure $ callback ) {}
10
+ private bool $ active = true ;
11
+
12
+ private function __construct (
13
+ /** @var \Closure(): void */
14
+ private readonly \Closure $ callback ,
15
+ ) {}
16
+
17
+ /**
18
+ * Detach the reaper from its target
19
+ *
20
+ * ```php
21
+ * $a = (object) [];
22
+ *
23
+ * $reaper = Reaper::watch($a, function () { echo "Good Bye"; });
24
+ * $reaper->forget();
25
+ *
26
+ * unset($b);
27
+ * // prints nothing
28
+ * ```
29
+ */
30
+ public function forget (): void
31
+ {
32
+ $ this ->active = false ;
33
+ }
11
34
12
35
/**
13
36
* Attach a callback to an object to be called when that object is destroyed.
@@ -52,16 +75,22 @@ private function __construct(private readonly \Closure $callback) {}
52
75
*
53
76
* @param callable(): void $callback
54
77
*/
55
- public static function watch (object $ subject , callable $ callback ): void {
78
+ public static function watch (object $ subject , callable $ callback ): self
79
+ {
56
80
self ::$ dd ??= new \WeakMap ();
57
81
58
82
self ::$ dd [$ subject ] ??= [];
59
83
60
- self ::$ dd [$ subject ][] = new self (\Closure::fromCallable ($ callback ));
84
+ return self ::$ dd [$ subject ][] = new self (\Closure::fromCallable ($ callback ));
61
85
}
62
86
63
87
/** @nodoc */
64
- public function __destruct () {
88
+ public function __destruct ()
89
+ {
90
+ if (!$ this ->active ) {
91
+ return ;
92
+ }
93
+
65
94
($ this ->callback )();
66
95
}
67
96
}
0 commit comments