Add ReflectionFunctionAbstract::isAnonymous()

php.internals

Dylan K. Taylor

4 years ago
Hi all, Given the addition of Closure::fromCallable() and the upcoming first-class callable syntax in 8.1, it seems slightly problematic that there's no simple way to tell by reflection if a Closure refers to an anonymous function or not. ReflectionFunctionAbstract::isClosure() (perhaps somewhat misleadingly) returns whether the closure is literally a \Closure instance, so it's not useful for this purpose. The only way to do this currently (that I know about) is to check if the name of the function contains "{closure}", which is a bit unpleasant and depends on undocumented behaviour. I'm proposing the addition of ReflectionFunctionAbstract::isAnonymous(), which would fill this use case, and may be able to offer an implementation. Thanks, Dylan Taylor.

Nikita Popov

4 years ago
On Thu, Oct 21, 2021 at 1:12 AM Dylan K. Taylor <dktapps@pmmp.io> wrote:
> Hi all, > > Given the addition of Closure::fromCallable() and the upcoming first-class > callable syntax in 8.1, it seems slightly problematic that there's no > simple way to tell by reflection if a Closure refers to an anonymous > function or not. ReflectionFunctionAbstract::isClosure() (perhaps somewhat > misleadingly) returns whether the closure is literally a \Closure instance, > so it's not useful for this purpose. > > The only way to do this currently (that I know about) is to check if the > name of the function contains "{closure}", which is a bit unpleasant and > depends on undocumented behaviour. > > I'm proposing the addition of ReflectionFunctionAbstract::isAnonymous(), > which would fill this use case, and may be able to offer an implementation. >
Sounds reasonable to me! Nikita

Aaron Piotrowski

4 years ago
> On Oct 20, 2021, at 6:12 PM, Dylan K. Taylor <dktapps@pmmp.io> wrote: > > Hi all, > > Given the addition of Closure::fromCallable() and the upcoming first-class callable syntax in 8.1, it seems slightly problematic that there's no simple way to tell by reflection if a Closure refers to an anonymous function or not. ReflectionFunctionAbstract::isClosure() (perhaps somewhat misleadingly) returns whether the closure is literally a \Closure instance, so it's not useful for this purpose. > > The only way to do this currently (that I know about) is to check if the name of the function contains "{closure}", which is a bit unpleasant and depends on undocumented behaviour. > > I'm proposing the addition of ReflectionFunctionAbstract::isAnonymous(), which would fill this use case, and may be able to offer an implementation. > > Thanks, > Dylan Taylor. > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >
Hi Dylan, I recently wrote some code checking for “{closure}”: https://github.com/amphp/amp/blob/27219ddbc0bbc3fd0db4d7380eaed6489c7291ed/lib/functions.php#L135 <https://github.com/amphp/amp/blob/27219ddbc0bbc3fd0db4d7380eaed6489c7291ed/lib/functions.php#L135> I agree, it is a bit unpleasant and looks like a hack. I would welcome an isAnonymous() method. Cheers, Aaron Piotrowski

Claude Pache

4 years ago
> Le 21 oct. 2021 à 01:12, Dylan K. Taylor <dktapps@pmmp.io> a écrit : > > Hi all, > > Given the addition of Closure::fromCallable() and the upcoming first-class callable syntax in 8.1, it seems slightly problematic that there's no simple way to tell by reflection if a Closure refers to an anonymous function or not. ReflectionFunctionAbstract::isClosure() (perhaps somewhat misleadingly) returns whether the closure is literally a \Closure instance, so it's not useful for this purpose. > > The only way to do this currently (that I know about) is to check if the name of the function contains "{closure}", which is a bit unpleasant and depends on undocumented behaviour. > > I'm proposing the addition of ReflectionFunctionAbstract::isAnonymous(), which would fill this use case, and may be able to offer an implementation. > > Thanks, > Dylan Taylor. > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >
Hi, Per the manual [1], Closure::fromCallable() “creates and returns a new anonymous function”. I guess that this might not match your notion of “anonymous function”? Therefore, I am asking for clarification: What practical distinction do you make between ”an instance of Closure” and “an anonymous function”, and why does this distinction matter? [1]: https://www.php.net/manual/en/closure.fromcallable.php <https://www.php.net/manual/en/closure.fromcallable.php> —Claude

Dylan K. Taylor

4 years ago
---- On Fri, 22 Oct 2021 14:19:23 +0100 Claude Pache <claude.pache@gmail.com> wrote ----
> > Le 21 oct. 2021 à 01:12, Dylan K. Taylor <dktapps@pmmp.io> a écrit : > > Hi all, > > Given the addition of Closure::fromCallable() and the upcoming first-class callable syntax in 8.1, it seems slightly problematic that there's no simple way to tell by reflection if a Closure refers to an anonymous function or not. ReflectionFunctionAbstract::isClosure() (perhaps somewhat misleadingly) returns whether the closure is literally a \Closure instance, so it's not useful for this purpose. > > The only way to do this currently (that I know about) is to check if the name of the function contains "{closure}", which is a bit unpleasant and depends on undocumented behaviour. > > I'm proposing the addition of ReflectionFunctionAbstract::isAnonymous(), which would fill this use case, and may be able to offer an implementation. > > Thanks, > Dylan Taylor. > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > > > Hi, > > Per the manual [1], Closure::fromCallable() “creates and returns a new anonymous function”. I guess that this might not match your notion of “anonymous function”? > > Therefore, I am asking for clarification: What practical distinction do you make between ”an instance of Closure” and “an anonymous function”, and why does this distinction matter? > > [1]: https://www.php.net/manual/en/closure.fromcallable.php > > —Claude >
Hi Claude, Sorry for the double email, my previous reply got bounced from the mailing list because I replied from the wrong address. An anonymous function would be an unnamed function, e.g. arrow function or function(){}. I guess the documentation for Closure::fromCallable() ought to be updated, because Closure::fromCallable('namedFunc') isn't really anonymous, it's a \Closure object that refers to a named function. A \Closure may refer to a named or an anonymous function, and currently there's no way to tell the difference without hacks. The distinction is important for reflection cases, such as the one Aaron mentioned, and also like generating a pretty name for closures in a project I maintain [1]. It's a fringe use case for sure, but considering we already have ReflectionClass->isAnonymous(), I think it makes sense. [1]: https://github.com/pmmp/PocketMine-MP/blob/986b4e0651d665c72ec011542f95b4bd9529c6a8/src/pocketmine/utils/Utils.php#L144 Dylan

Nicolas Grekas

4 years ago
Le ven. 22 oct. 2021 à 15:41, Dylan K. Taylor <dktapps@pmmp.io> a écrit :
> > ---- On Fri, 22 Oct 2021 14:19:23 +0100 Claude Pache < > claude.pache@gmail.com> wrote ---- > > > > > Le 21 oct. 2021 à 01:12, Dylan K. Taylor <dktapps@pmmp.io> a écrit : > > > > Hi all, > > > > Given the addition of Closure::fromCallable() and the upcoming > first-class callable syntax in 8.1, it seems slightly problematic that > there's no simple way to tell by reflection if a Closure refers to an > anonymous function or not. ReflectionFunctionAbstract::isClosure() (perhaps > somewhat misleadingly) returns whether the closure is literally a \Closure > instance, so it's not useful for this purpose. > > > > The only way to do this currently (that I know about) is to check if > the name of the function contains "{closure}", which is a bit unpleasant > and depends on undocumented behaviour. > > > > I'm proposing the addition of > ReflectionFunctionAbstract::isAnonymous(), which would fill this use case, > and may be able to offer an implementation. > > > > Thanks, > > Dylan Taylor. > > > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > > > > > Hi, > > > > Per the manual [1], Closure::fromCallable() “creates and returns a new > anonymous function”. I guess that this might not match your notion of > “anonymous function”? > > > > Therefore, I am asking for clarification: What practical distinction do > you make between ”an instance of Closure” and “an anonymous function”, and > why does this distinction matter? > > > > [1]: https://www.php.net/manual/en/closure.fromcallable.php > > > > —Claude > > > > Hi Claude, > Sorry for the double email, my previous reply got bounced from the mailing > list because I replied from the wrong address. > > An anonymous function would be an unnamed function, e.g. arrow function or > function(){}. > > I guess the documentation for Closure::fromCallable() ought to be updated, > because Closure::fromCallable('namedFunc') isn't really anonymous, it's a > \Closure object that refers to a named function. A \Closure may refer to a > named or an anonymous function, and currently there's no way to tell the > difference without hacks. > > The distinction is important for reflection cases, such as the one Aaron > mentioned, and also like generating a pretty name for closures in a project > I maintain [1]. > > It's a fringe use case for sure, but considering we already have > ReflectionClass->isAnonymous(), I think it makes sense. > > [1]: > https://github.com/pmmp/PocketMine-MP/blob/986b4e0651d665c72ec011542f95b4bd9529c6a8/src/pocketmine/utils/Utils.php#L144 > > >
For the record, I submitted a PR adding ReflectionFunction::isAnonymous() at https://github.com/php/php-src/pull/8499 Cheers, Nicolas