This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 216027 - Variables in closures are scoped to the containing scope
Summary: Variables in closures are scoped to the containing scope
Status: VERIFIED FIXED
Alias: None
Product: php
Classification: Unclassified
Component: Editor (show other bugs)
Version: 7.2
Hardware: All All
: P3 normal (vote)
Assignee: Ondrej Brejla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-26 18:55 UTC by dharkness
Modified: 2012-09-05 09:37 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dharkness 2012-07-26 18:55:02 UTC
When you have two closures that use the same variable name, NetBeans treats them as the same variable even though they are in different scopes.

THE GOOD

Without the second closure, the detection works fine. NetBeans shows an indicator for the line and underlines $index because it is never used.

  EXPECTED == OBSERVED

    function test() {
      function ($index) { };
                ^^^^^^ Variable $index seems to be unused
    }

THE BAD

However, if you add a second closure in the same method that receives a variable with the same name that isn't used, neither declaration is flagged as unused. NetBeans appears to think the second declaration is a usage.

  EXPECTED

    function test() {
      function ($index) { };
                ^^^^^^ Variable $index seems to be unused
      function ($index) { };
                ^^^^^^ Variable $index seems to be unused
    }

  OBSERVED

    No warnings for either use of $index

THE UGLY

Finally, if you add a second closure that uses the same variable name for a local variable inside the closure body, it also causes NetBeans to treat it as a usage of the first variable.

  EXPECTED

    function test() {
      function ($index) { };
                ^^^^^^ Variable $index seems to be unused
      function () { $index = 5; };
                    ^^^^^^ Variable $index seems to be unused
    }

  OBSERVED

    No warnings for either use of $index
Comment 1 Ondrej Brejla 2012-07-27 07:00:14 UTC
It's not so simple, because scope of that $index var is not just the body of closure, but the body of enclosing function too. Because that variable is declared in outer scope, so "usage" of it is that usage as a closure param.

I think that ve are not able to handle these both cases, since it's still the one physical variable. And it's primary scope is outer scope...scope of it's declaration.

So for me, it works as intended (it was designed to work this way). But I will let it opened as a reminder. 
Thanks for reporting.
Comment 2 dharkness 2012-07-27 07:26:07 UTC
Variables declared immediately after the "function" keyword are local to the closure. Their values are provided when the closure is called. They function exactly as declared parameters for regular functions.

    function foo() {
        $bar = 'bar';
        $closure = function ($bar) {
            var_dump($bar);
            $bar = 'bye';
        };
        $closure('hi');
        var_dump($bar);
    }

    foo();

Output:

    string(2) "hi"
    string(3) "bar"

However, variables declared in the optional "use" clause *are* the same variables from the enclosing scope. The "use" block allows you to pass variables from the enclosing scope to the closure. This is why you must declare a local variable such as "$self" so you can pass $this to the closure; the closure doesn't have access to $this.

    function foo() {
        $bar = 'bar';
        $closure = function () use (&$bar) {
            var_dump($bar);
            $bar = 'bye';
        };
        $closure();
        var_dump($bar);
    }

    foo();

Output:

    string(3) "bar"
    string(3) "bye"
Comment 3 Ondrej Brejla 2012-07-27 07:28:31 UTC
Oooouuuu...yes, you are definitelly right. My bad. Sorry. Thanks.
Comment 4 Ondrej Brejla 2012-07-27 08:57:39 UTC
Fixed in web-main #a3e23bd95b9f
Comment 5 Quality Engineering 2012-07-28 02:22:30 UTC
Integrated into 'main-golden', will be available in build *201207280002* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/a3e23bd95b9f
User: Ondrej Brejla <obrejla@netbeans.org>
Log: #216027 - Variables in closures are scoped to the containing scope
Comment 6 Ondrej Brejla 2012-08-08 08:09:53 UTC
Vlado, please, can you verify that for 7.2 patch 1? Thanks in advance.
Comment 7 Vladimir Riha 2012-08-08 09:04:02 UTC
verified

Product Version: NetBeans IDE Dev (Build 201208080001)
Java: 1.7.0_06; Java HotSpot(TM) Client VM 23.2-b09
System: Linux version 3.0.0-23-generic running on i386; UTF-8; en_US (nb)
Comment 8 Ondrej Brejla 2012-08-09 08:37:43 UTC
Transplanted into releases, please verify, thanks.
Comment 9 Quality Engineering 2012-09-01 11:11:10 UTC
Integrated into 'releases', will be available in build *201209010822* or newer. Wait for official and publicly available build.
Changeset: http://hg.netbeans.org/releases/rev/edaf720e6bf7
User: Ondrej Brejla <obrejla@netbeans.org>
Log: #216027 - Variables in closures are scoped to the containing scope
(transplanted from a3e23bd95b9f86edca04a8098acea68c4d13f6a2)
Comment 10 Vladimir Riha 2012-09-05 09:37:48 UTC
verified in patch

Product Version: NetBeans IDE 7.2 (Build 201207171143)
Java: 1.7.0_06; Java HotSpot(TM) Client VM 23.2-b09
System: Linux version 3.2.0-29-generic-pae running on i386; UTF-8; en_US (nb)