If you had use warnings in the script you'd see something like "my" variable $foo masks earlier declaration in same scope at scriptname.pl line 6.
I'm pretty sure that Perl is parsing the script prior to actually executing it, seeing the second declaration of $foo which masks the first declaration, and using that second variable in the same scope to actually execute the script. So you're calling the subroutine before defining the second $foo, meaning you print an uninitialized value.
You would see the same output if you had a script like
use strict;
foo();
my $foo = 2;
sub foo {
print "foo: $foo\n";
}