On Fri, Nov 24, 2023 at 11:27 AM Michał Marcin Brzuchalski <michal.brzuchal...@gmail.com> wrote: > > Hi Robert, > > pt., 24 lis 2023 o 10:24 Robert Landers <landers.rob...@gmail.com> napisał(a): >> >> ... >> You can also emulate this with: >> >> class Defer { >> private function __construct(private \Closure $callback) {} >> public function __destruct() { $this->callback(); } >> public static function _(\Closure $callback) { return new self($callback); >> } >> } >> >> and use it like: >> >> function writeSomeStuff() { >> // open files >> $deferred = Defer::_($closeFiles(...)); >> // do stuff >> } >> >> So long as a reference exists to $deferred variable, the deferred >> method won't be run. If the variable is local to the method/function >> being run it, the deconstructor will be called after the function >> returns. >> >> It isn't the most beautiful thing in the world, and easy to forget to >> store the result of Defer, but it is handy sometimes. > > > This is interesting which makes me thinking if forget to store it could be > prevented. > I think requiring a ref could help with that: > > class Defer { > private function __construct(private \Closure $callback) {} > public function __destruct() { ($this->callback)(); } > public static function _(\Closure $callback, &$var) { $var = new > self($callback); } > } > > $deferred = Defer::_($closeFiles(...), $foo); > > Without $foo there'd be an ArgumentCountError. > > Cheers, > Michał Marcin Brzuchalski
Hey Michael, Thinking about it some more, I think we can go even further than that and actually implement defer (enjoying the code golf)! function defer(mixed &$anchor, \Closure $deferred): void { if(is_resource($anchor)) { $anchor = new class($anchor) { public function __construct(public readonly mixed $resource) {} }; } static $mapping = new WeakMap(); $mapping[$anchor] = new class($deferred) { public function __construct(private \Closure $deferred) {} public function __destruct() { ($this->deferred)(); } }; } function writeFiles() { $handle = fopen("/tmp/scratch.php", "wb"); // todo: write data defer($handle, static function() use ($handle) { echo "\ndeferred\n"; fclose($handle); }); echo "\nafter defer()\n"; } writeFiles(); echo "\nafter writeFiles()\n"; or something like that. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php