Similar to a tick event, an async function will be called automatically after the block of code .
and the async function is cleared when script shutown.
Async function can be cleared after they have returned, or they can continue to be called at the next event after they have returned.
and some of the features of Fiber
Hi,
You probably want something similar to golang's defer keyword.
I intend to submit an RFC and PR for a defer keyword in PHP sometime in
the future.
Regards,
Daniil Gentili.
Similar to a tick event, an async function will be called automatically after the block of code .
and the async function is cleared when script shutown.
Async function can be cleared after they have returned, or they can continue to be called at the next event after they have returned.
and some of the features of Fiber
I think you want a flattened
try {
// do stuff
} finally {
// clean up
}
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.
Robert Landers
Software Engineer
Utrecht NL
Hi Robert,
pt., 24 lis 2023 o 10:24 Robert Landers landers.robert@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
On Fri, Nov 24, 2023 at 11:27 AM Michał Marcin Brzuchalski
michal.brzuchalski@gmail.com wrote:
Hi Robert,
pt., 24 lis 2023 o 10:24 Robert Landers landers.robert@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.
Hi,
Thinking about it some more, I think we can go even further than that
and actually implement defer (enjoying the code golf)!
Dropping this here, just in case :)
https://github.com/php-defer/php-defer
From the posts on this thread (and the star count on php-defer), it
seems there is indeed some interest in a defer keyword for PHP, might
actually get to writing an RFC implementing the keyword itself this
weekend...
Regards,
Daniil Gentili.