It is a bug. As it is written in the tractate Camel III 4:132:
in reply to Re: Unusual Closure Behaviour
in thread Unusual Closure Behaviour
Lexicals are hidden from any subroutine called from their scope. This is true even if the same subroutine is called from itself or elsewhere—each instance of the subroutine gets its own "scratchpad" of lexical variables.
$x is clearly a lexical. Its scope is inside foo. Yet each instance of foo is not getting its own scratchpad of lexical variables. Hence, we have a creepy crawly thing of uncertain appeal...a bug.
Update 2: One might argue that the anomalous behavior of $x is consistent with the above dictum, because the subroutine foo is not being called from scope of $x. However, when the Perl wise ones write that lexicals are hidden from any subroutine called from their scope, it means even if they are called from their scope.
If a lexical is hidden from subroutines called from inside its own scope, then how much more so must it be hidden from subroutines called from outside its own scope.
As Abigail has taught, conditionally declaring lexicals for use in subroutines is an example of "an ox that is known to gore," i.e., its behavior is going to be ambiguous. Even though it is legal to release such an ox and let it run around and possibly damage a neighbor's code, let us instead "build a fence around the Law" and only declare lexical variables in subroutines unconditionally, outside of conditional branching such as 'my $x if 0'.
(previous updates effaced)