Nested functions

From: Date: Thu, 13 Aug 2020 14:35:33 +0000
Subject: Nested functions
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-111506@lists.php.net to get a copy of this message
13.08.2020, 10:52, "Claude Pache" <claude.pache@gmail.com>: >> Le 12 août 2020 à 22:05, Luis - SoftSAT Sistemas <luis@softsatsistemas.com.br> a >> écrit : >> >>>>  Le 12 août 2020 à 20:19, Luis - SoftSAT Sistemas >>>> <luis@softsatsistemas.com.br> a écrit : >>>> >>>>  In the effort to make PHP a better language i want to ask why not "fix" >>>> nested functions as suggested in (https://wiki.php.net/rfc/true-nested-function-support) or block >>>> their usage? >>>>  The current behavior is a lot unexpected. >>>> >>>>  I am new here, sorry if it was already discussed, i can't find a good way to >>>> search the mailing history. >>> >>> Hi, >>> >>> Defining a global function inside another function is not useless. Here is a dummy >>> example: >>> >>> ```php >>> // a.php >>> spl_autoload_register(function ($classname) { >>>     if ($classname === 'Foo\\B') >>>         require 'foo/b.php'; >>> }) >>> >>> // foo/b.php >>> namespace Foo; >>> >>> class B { >>>     // ... >>> } >>> >>> function some_helper(....$args) { >>>     // ... >>> } >>> ``` >>> >>> The global function Foo\some_helper is defined inside >>> the function used as autoloader. >>> >>> Also, from the RFC: >>> >>>>  They exist in the global namespace. >>> >>> I think you meant “They exist in the global scope”? because they are defined in the >>> namespace corresponding to the eventual namespace declaration of the >>> file. >>> >>> —Claude >> >> You are right Claude, i wasn't thinking about this use case. >> >> But outside of this use case more problems arise. >> If foo/b.php  have some global variable and some function >> that use it the function breaks because the global variable will be "included" into >> current scope, while the functions into namespace scope. >> ```php >> //a.php >> function foo() { >>    require 'b.php'; >>    //var_dump($something); >> } >> >> foo(); >> >> var_dump(bar()); >> >> //b.php >> $something = 10; >> >> function bar() { >>    global $something; >>    return $something; >> } >> ``` >> I expected the var_dump(bar()); output to be >> int (10), but it was NULL, while if >> i do var_dump($something); from >> foo() it outputs int(10) as >> "normally expected". >> Given that "bar()" are at namespace scope, this can be "fixed" changing >> $something = 10; to $GLOBALS['something'] >> = 10;, but that doesn't change the fact that this behavior are odd and not >> intuitive. >> >> PS: I known that global variables are a bad thing, it was just an example. >> >> Anyway now i see that changing this will break the auto loader system. >> >> About the RFC you are right, they are wrong about the scope, but the RFC aren't mine, >> i just found it while searching about the subject. >> >> --L. Henrique > About global variables; it is an issue I encountered once upon a time when refactoring code. > The short term solution is to declare the global variables both in the inner and the outer scope: > > ```php > // b.php > global $something; > > $something = 10; > > function bar() { >    global $something; >    return $something; > } > ``` > > Functions in PHP have the following characteristics: they are defined globally, and they > don’t inherit variables from their parent scope. On the other hand, anonymous functions (closures) > are available locally, and they may import variables from their parent scope. Both sort of functions > have their usages. > > About the RFC page: It looks to me like an old abandoned stub. It isn’t even listed > on https://wiki.php.net/rfc > > —Claude I think it's all clear now, thanks Claude! -- L. Henrique

« previous php.internals (#111506) next »