"Chas. Owens" <chas.ow...@gmail.com> writes: > I have attached my first draft of the documentation (they include > brian d foy's changes from last night).
You're awesome. Thank you *so* much! > diff --git a/pod/perlmod.pod b/pod/perlmod.pod > index d6ddd83..44d5924 100644 > --- a/pod/perlmod.pod > +++ b/pod/perlmod.pod > @@ -273,6 +273,11 @@ and such from other files in time to be visible to the > rest of the compile > and run time. Once a C<BEGIN> has run, it is immediately undefined and any > code it used is returned to Perl's memory pool. > > +Inside of a C<BEGIN> block, the C<${^GLOBAL_PHASE}> variable will be set to > +C<"START">, unless the C<BEGIN> block was executed by C<require>, string > +C<do>, or string C<eval>. In those cases the C<${^GLOBAL_PHASE}> will be > +set to the phase the C<require>, C<do>, or string C<eval> was executed in. I find that rather confusing. Of course ${^GLOBAL_PHASE} is, during a certain phase, always set to the phase that's currently running :-) Saying that a value of "START" will only be present in some BEGIN-blocks is a little misleading. While that's true, as everything where ${^GLOBAL_PHASE} will have a value of "START" will be run from a BEGIN-block in the main program, it's easy to get that value from code which doesn't directly contain such a block. For example BEGIN { require Foo } and in Foo.pm is ${^GLOBAL_PHASE}, "START"; The run-time of Foo.pm happens during the compile-time of the main program. I think focusing too much on BEGIN-blocks while trying to explaining "START" might be a mistake. To avoid this kind of confusion is why I called the value "START" instead of "BEGIN" in the first place. > C<UNITCHECK>, C<CHECK> and C<INIT> code blocks are useful to catch the > transition between the compilation phase and the execution phase of > the main program. > @@ -302,15 +310,31 @@ C<UNITCHECK> blocks are run just after the unit which > defined them has > been compiled. The main program file and each module it loads are > compilation units, as are string C<eval>s, code compiled using the > C<(?{ })> construct in a regex, calls to C<do FILE>, C<require FILE>, > -and code after the C<-e> switch on the command line. > +and code after the C<-e> switch on the command line. So long as the > +C<UNITCHECK> is not executed by a C<require>, C<do>, or string C<eval>, > +the value of the C<${^GLOBAL_PHASE}> variable will be set to C<"START">, > +otherwise it will be set to the phase the C<require>, C<do>, or > +string C<eval> ran in. > + > +Inside of a C<UNITCHECK> block, the C<${^GLOBAL_PHASE}> variable will be > +set to C<"START">, unless the C<UNITCHECK> block was executed by C<require>, > +string C<do>, or string C<eval>. In those cases the C<${^GLOBAL_PHASE}> > +will be set to the phase the C<require>, C<do>, or string C<eval> was > +executed in. I'm not sure explaining what values ${^GLOBAL_PHASE} might have in UNITCHECK-blocks is too useful. It can be any of the possible values, except for "CONSTRUCT" (as you can't compile code during that phase), because you can compile code during any phase. > diff --git a/pod/perlvar.pod b/pod/perlvar.pod > index d3684a1..f159832 100644 > --- a/pod/perlvar.pod > +++ b/pod/perlvar.pod > @@ -503,8 +503,49 @@ Not every program has to go through each of the possible > phases, but > transition from one phase to another can only happen in the order > described in the above list. > > -The patch also includes some basic tests, if you prefer actual working > -examples of how C<${^GLOBAL_PHASE}> behaves. > +An example of all of the phases Perl code can see: > + > + BEGIN { print "compile-time: ${^GLOBAL_PHASE}\n" } > + > + INIT { print "init-time: ${^GLOBAL_PHASE}\n" } > + > + CHECK { print "check-time: ${^GLOBAL_PHASE}\n" } > + > + { > + package Print::Phase; > + > + sub new { > + my ($class, $time) = @_; > + return bless \$time, $class; > + } > + > + sub DESTROY { > + my $self = shift; > + print "$$self: ${^GLOBAL_PHASE}\n"; > + } > + } > + > + print "run-time: ${^GLOBAL_PHASE}\n"; > + > + my $runtime = Print::Phase->new( > + "lexical variables are garbage collected before END" > + ); > + > + END { print "end-time: ${^GLOBAL_PHASE}\n" } > + > + our $destruct = Print::Phase->new( > + "package variables are garbage collected after END" > + ); > + > +This will print out > + > + compile-time: START > + check-time: CHECK > + init-time: INIT > + run-time: RUN > + lexical variables are garbage collected before END: RUN > + end-time: END > + package variables are garbage collected after END: DESTRUCT I love that example. Also illustrating what happens when loading code with `use', both during and outside of the global compile-time phase might be cool, but I'm not really sure how that could be done. > diff --git a/pod/perlmod.pod b/pod/perlmod.pod > index eaa8ba9..d6ddd83 100644 > --- a/pod/perlmod.pod > +++ b/pod/perlmod.pod > @@ -311,10 +311,11 @@ in the Perl compiler suite to save the compiled state > of the program. > C<INIT> blocks are run just before the Perl runtime begins execution, in > "first in, first out" (FIFO) order. > > -The C<CHECK> and C<INIT> code blocks will not be executed inside a string > -eval(), if that eval() happens after the end of the main compilation > -phase; that can be a problem in mod_perl and other persistent environments > -which use C<eval STRING> to load code at runtime. > +The C<CHECK> and C<INIT> blocks in code executed by C<require>, string C<do> > +, or string C<eval> will not be executed if they occur after the end of the > +main compilation phase (i.e. they are not in a C<BEGIN> block); that can be ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Again - true, but slightly misleading. They only have to indirectly be within a BEGIN-block in the main compilation unit, which isn't always obvious to see. This is awesome work. Many thanks to both of you! :-)
pgpsaEF8AwA7V.pgp
Description: PGP signature