No it hasn't. You seem to be confusing Foo with the anonymous sub
- BEGIN { ... } is compiled.
- my $x = 12345; is compiled.
- *Foo = sub(){ $x }; is compiled.
- BEGIN { ... } is executed.
- my $x = 12345; is executed.
- *Foo = sub(){ $x }; is executed. ⇐ &Foo is declared and defined here.
- print Foo() is compiled. ⇐ &Foo is known to be constant.
- [ Execution phase starts ]
- print 12345 is executed.
vs
- { ... } is compiled.
- my $x = 12345; is compiled.
- *Foo = sub(){ $x }; is compiled.
- print Foo() is compiled. ⇐ &Foo is implicitly declared and called as a plain sub here.
- [ Execution phase starts ]
- { ... } is executed.
- my $x = 12345; is executed.
- *Foo = sub(){ $x }; is executed. ⇐ &Foo is defined here.
- print &Foo() is executed.
In fact, the prototype is always completely ignored if the subroutine call is compiled before the prototype is added.
*Foo = sub($) { print "$_[0]\n" };
sub Bar($) { print "$_[0]\n" }
my @array = qw( a b c );
Foo(@array); # a
Bar(@array); # 3