On Fri, Nov 24, 2023 at 11:27 AM Michał Marcin Brzuchalski
<[email protected]> wrote:
>
> Hi Robert,
>
> pt., 24 lis 2023 o 10:24 Robert Landers <[email protected]> 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