Bug #78970 [Com]: Compact can't resolve outer scoped variables using short closures X-PHP-Bug: 78970 X-PHP-Site: PHP X-PHP-Type: Bug X-PHP-Version:
7.4.0 X-PHP-Category: Arrays related X-PHP-OS: Linux/Any X-PHP-Status: Verified X-PHP-Old-Status: Verified In-Reply-To: <bug-78970@bugs.php.net>

From: Date: Fri, 17 Nov 2023 18:33:54 +0000
Subject: Bug #78970 [Com]: Compact can't resolve outer scoped variables using short closures X-PHP-Bug: 78970 X-PHP-Site: PHP X-PHP-Type: Bug X-PHP-Version:
7.4.0 X-PHP-Category: Arrays related X-PHP-OS: Linux/Any X-PHP-Status: Verified X-PHP-Old-Status: Verified In-Reply-To: <bug-78970@bugs.php.net>
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-245831@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78970&edit=1 ID: 78970 Comment by: piurafunk at gmail dot com Reported by: stanislav dot goldmann at gmail dot com Summary: Compact can't resolve outer scoped variables using short closures Status: Verified Type: Bug Package: Arrays related Operating System: Linux/Any PHP Version: 7.4.0 Block user comment: N Private report: N New Comment: I believe this also applies to require-ing a file. Context: Working in the Laravel task scheduler. I have 2 relevant files: tasks/sales.php --- <?php use App\Console\Commands\Command; /** @var \Illuminate\Console\Scheduling\Schedule $schedule */ return [ $schedule->command(Command::class)->cron('* * * * *'), ]; --- app/Console/Kernel.php --- ... ->map(fn(SplFileInfo $file) => require $file->getPathname()) ... --- Results in an exception: --- ErrorException Undefined variable $schedule at tasks/sales.php:8 4▕ 5▕ use App\Console\Commands\Command; 6▕ 7▕ return [ ➜ 8▕ $schedule->command(Command::class)->cron('* * * * *'), 9▕ ]; 10▕ --- Whereas a traditional closure with use() works fine: --- ->map(function (SplFileInfo $file) use ($schedule) { return require $file->getPathname(); }) --- Previous Comments: ------------------------------------------------------------------------ [2019-12-16 13:52:14] nikic@php.net Due to lack of varvar support in arrow functions. Not going to be entirely simple. ------------------------------------------------------------------------ [2019-12-16 13:37:14] stanislav dot goldmann at gmail dot com Description: ------------ In the proposal of short closures (https://wiki.php.net/rfc/arrow_functions_v2) the following is stated: "When a variable used in the expression is defined in the parent scope it will be implicitly captured by-value." With this example: $y = 1; $fn1 = fn($x) => $x + $y; $fn2 = function ($x) use ($y) { return $x + $y; }; These two behave exactly the same, as expected. However compact doesn't behave that way, as it doesn't recognize a variable from outer scope until it is explicitly called. Test script: --------------- $name = 'foo'; $array = ['bar']; $failing = fn($value) => compact('name', 'value'); $working = fn($value) => compact('name', 'value') + [$name]; var_dump(array_map($failing, $array)); var_dump(array_map($working, $array)); Expected result: ---------------- Short closures using compact should resolve outer scoped variables and behave like "long" closures using an use statement. fn($value) => compact('name', 'value') should work just like function($value) use ($name) { return compact('name', 'value'); } And return the following array(1) { [0]=> array(3) { ["name"]=> string(3) "foo" ["value"]=> string(3) "bar" } } Actual result: -------------- // Notice: compact(): Undefined variable: name array(1) { [0]=> array(1) { ["value"]=> string(3) "bar" } } ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78970&edit=1

« previous php.bugs (#245831) next »