Q:

Perl Function Scoping with my

I am confused with the behavior difference between the following two code segments:
$x = 8;
sub a {
    sub b {
        print "B: $x\n";
    }
    my $x = 3;
    &b();
}
&a();

and 
$x = 8;
sub a {
    my $x = 3;
    sub b {
        print "B: $x\n";
    }
    &b();
}
&a();

While the first one outputs B:8, the second one outputs B:3. Shouldn't they output the same value, as the outer scope of sub b should be sub a? How does the different placements of functions make a difference? 

A:

Others have already pointed out the issue with nested subs, but here is my answer to my understanding of your question:
The "scope" of a my declaration begins after the statement that contains the my, not at the beginning of the block it occurs in. Otherwise, both of these would work:
$ perl -wMstrict -le 'sub foo { my $bar="quz"; print $bar; } foo()'
quz
$ perl -wMstrict -le 'sub foo { print $bar; my $bar="quz"; } foo()'
Global symbol "$bar" requires explicit package name (did you forget to declare "my $bar"?) at -e line 1.
Execution of -e aborted due to compilation errors.

Also, note the following:
my $x = 3;
{
    my $x = $x + 5;
    print "1: $x\n";  # prints "1: 8"
}
print "2: $x\n";      # prints "2: 3"

In your first piece of code, at the point you declare sub b, Perl only knows about the global $x = 8, so that's what print "B: $x\n" is using. In the second piece of code, Perl has seen my $x = 3, so that's what it uses. This effect also occurs if you don't use nested subs:
my $x = 8;
sub a {
    my $subb = sub {
        print "B: $x\n";
    };
    my $x = 3;
    $subb->();
}
a();  # prints "B: 8"

and
my $x = 8;
sub a {
    my $x = 3;
    my $subb = sub {
        print "B: $x\n";
    };
    $subb->();
}
a();  # prints "B: 3"

A:

This problem arises from having nested named subs.
There's no reason to have nested name subs in Perl since the inner sub is in no way scoped to the outer sub.
Instead, use:
sub p {
    my ($x) = @_;

    local *q = sub {
        say $x;
    };

    q();
}

p($_) for 3, 4;

or
sub p {
    my ($x) = @_;

    my $q = sub {
        say $x;
    };

    $q->();
}

p($_) for 3, 4;

