The reason is because
$foo = 20 doesn't occur until after you've called all those functions.
DECLARATION occurs at compile-time. ASSIGNMENT happens at run-time. Different things.
my $foo = 20 has a compile-time effect (
my) and a run-time effect (
$foo = 20).
For your desired action, you'd need something like:
my $foo;
BEGIN { $foo = 20 }
japhy --
Perl and Regex Hacker