in reply to BEGIN block and prototyped subroutines

You seem to misunderstand both BEGIN and prototypes.

Let's look at BEGIN first. It causes the enclosed code to be executed as soon as it is compiled.

For the following code:

print "a"; BEGIN { print "b"; } print "c";

the following happens:

BEGIN is completely useless around a sub definition because a sub definition doesn't produce any runnable code.

Now, let's look at prototypes. Prototypes affect how sub calls are parsed and they affect the code into which a sub call is compiled. Obviously, that means the prototype of a sub must be known at the time a call to the sub is encountered.

For the following code:

foo('bar'); sub foo($) { print "foo called: @_\n"; }
the following happens:

You need to declare the sub before any calls to the sub are compiled. It's the only way the sub call can be affected by the prototype.

sob foo($); foo('bar'); sub foo($) { print "foo called: @_\n"; }

By the way, prototypes are by and large discouraged in Perl. They are not a good way to check the validity of arguments.