On Fri, Sep 26, 2003 at 08:13:07PM -0700, R. Joseph Newton wrote:
> Dan Anderson wrote:
> > use strict;
> > use warnings;
> >
> > END
> > {
> >     print "Look ma, i'm using subroutines!";
> 
> Shouldn't lie to your mama.  That is not a subroutine.  Its more a macro.
> I gets compiled vefore anything in the main namespace, other than another
> begin block.

It's an END block.  But I don't think "macro" is quite the right way
to describe BEGIN blocks, either.  I think of it like this: perl 
compiles your script from beginning to end, one token at a time.
When it sees a BEGIN block, it stops what it was doing (the main 
compilation) and begins a sub-compilation.  This recursive step
compiles whatever is inside the BEGIN block, right up to the closing
curly brace, and when that's finished, the code inside the BEGIN block
is executed.  Then Perl resumes the main compilation.  When the main
compilation is finished, the body of the script executes.

Inside the BEGIN block, subroutines and variable declarations
"earlier" in the script have already been compiled, which means that
this works:

  sub foo { "foo!" }
  BEGIN { print foo() }

But code "earlier" in the script hasn't been executed, which means
that this *doesn't* work.

  my $foo = "foo!";
  BEGIN { print $foo }

The $foo variable is declared, but it hasn't been initialized yet.

And besides, I thought the "Look, Ma!" was referring to this, which
really is a subroutine call --->

> >     foo::foo();

Anyway:

> > BEGIN
> > {
> >     package foo;
> 
> It cannot be called here, before [by definition, being a BEGIN block]
> compilation has begun.

But it can be called here.  And compilation has already begun -- 
everything before this BEGIN block has already been compiled.  The
subroutine call here even works!

The problem is that the subroutine call is *compiled* before the
subroutine-with-prototype is defined, which means that perl can't
check the prototype.

> >     foo();
> >     BEGIN
> >     {

And then when foo() is defined here with a prototype, perl remembers
that it already compiled some calls to it, and issues the warning.

> >         sub foo()
> >         { print "\nfoo\n"; }
> >     }

As a matter of fact, none of this has anything to do with BEGIN 
blocks; and you can demonstrate the same thing without them:

  % perl -we '
  foo(42);
  sub foo () {}
  sub bar () {}
  bar(42);
  '
  main::foo() called too early to check prototype at -e line 2.
  Too many arguments for main::bar at -e line 5, near "42)"
  Execution of -e aborted due to compilation errors.

You see that bar(42) is a compilation error.  foo(42) *should* be 
a compilation error, but perl had to skip the prototype check, and 
all it can do now is issue the "called too early" warning.

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to