What you don't understand is that perl compiles that sub foo and compiles the lexical-ness of the my declarations before it executes the foo() and before it sets those lexicals below the function call.
I think it's clearer like this. It's nearly the same thing, but it doesn't have the lexical masking that yours has. That just confuses the issue.
use strict;
use warnings;
foo();
my ($foo, $berries) = (1,2);
foo();
sub foo {
print "$foo, $berries\n";
}
Here you can clearly see I'm using the foo and berries declared lexically after the function is called. The declaration happens at compile time and the initialization happens at runtime.