SPUG: Modules - more than one object in file?

Darren/Torin/Who Ever... torin at daft.com
Wed Oct 11 16:01:47 CDT 2000


I came in a bit late to say much but I did want to make a few comments.
(Well, more than a few comments; my instructor side came out to play.)

Brian Ingerson, in an immanent manifestation of deity, wrote:
>There seems to be a lot of fuzziness among the common Perl community, as
>to what *order* Perl executes all of the source code that you give it.

It's really not fuzzy at all.  It is in a definitive order.  But I'll
grant that some folks ideas about the order is fuzzy. :)

>Perlers talk about 'compile time' and 'run time', but in reality the two
>are very much mixed together. For example you can use BEGIN blocks to
>'run' code during 'compile' time, and eval blocks to 'compile' Perl
>during 'run' time. 

I disagree about them being mixed together.  All code gets turned into
a parse tree during compile time.  Then, to run the code, Perl walks the
parse tree executing the ops that it finds along the way.

Perl does want to be quite the enabler though.  :)  It gives you hooks
so you can run code during compile time - why should the executable have
all the fun?  That's the BEGIN statement.

Perl also doesn't want to be discriminatory.  It likes to enable you on
both sides of the compile/run phase.  So, if in the middle of your
running code, you'd like to call the compiler again, you can do that
with eval.

No fuzziness whatsoever.  Perl just wants to give the programmer as much
control as possible.  At any point along the way, you can modify what is
going on.  Larry knows that -you- know -your- situation way better than
he ever will, so he gives you hooks to do whatever you want whenever you
want.  Try to convince the other language designers to give you that
kind of control.  (Heh.  Can you tell I like Perl?)

In summary (and in order):
BEGIN - run this code *NOW* as soon as the block is closed forgoing all
        else.
CHECK - run this code as late as possible in the compile stage.
INIT  - run this code as soon as possible in the run stage
END   - run this code as late as possible (in the run stage of course).

If you define these multiple times, Perl will accumulate them for you.

Both BEGIN and INIT will run in FIFO order - first in, first out.  To
me, this is the obvious order.

CHECK and END will run in LIFO order - last in, first out.  If you read
the descriptions, this will make sense even if it is somewhat
surprising.  Each one will run as late as possible but previously
defined CHECK/END blocks might have taken the very last place before
this one got to it.

Neither CHECK nor INIT are defined in 5.004.  CHECK isn't defined in 5.005.

Note that before 5.6, all these blocks would be run even if you
specified the -c switch.  With 5.6, -c will only run the BEGIN and CHECK
blocks.

I wrote the following to make sure I wasn't lying:
{2}[0]~ perv:-) perl-5.6 -we 'BEGIN {warn "begin 1\n";} BEGIN {warn "begin 2\n";}  
sub CHECK {warn "check 1\n";}  sub CHECK {warn "check 2\n";}
sub INIT {warn "init 1\n";} sub INIT {warn "init 2\n";}
END {warn "end 1\n";} sub END {warn "end 2\n";}'
begin 1
begin 2
check 2
check 1
init 1
init 2
end 2
end 1
{2}[0]~ perv:-) perl-5.005 -we 'BEGIN {warn "begin 1\n";} BEGIN {warn "begin 2\n";}
sub CHECK {warn "check 1\n";}  sub CHECK {warn "check 2\n";}
sub INIT {warn "init 1\n";} sub INIT {warn "init 2\n";}
END {warn "end 1\n";} sub END {warn "end 2\n";}'
begin 1
begin 2
Subroutine CHECK redefined at -e line 2.
init 1
init 2
end 2
end 1
{2}[0]~ perv:-) perl-5.004 -we 'BEGIN {warn "begin 1\n";} BEGIN {warn "begin 2\n";}
sub CHECK {warn "check 1\n";}  sub CHECK {warn "check 2\n";}
sub INIT {warn "init 1\n";} sub INIT {warn "init 2\n";}
END {warn "end 1\n";} sub END {warn "end 2\n";}'
begin 1
begin 2
Subroutine CHECK redefined at -e line 2.
Subroutine INIT redefined at -e line 3.
end 2
end 1


>   so you could infer, that 'BEGIN' is the only real compile time
>directive.

Well, CHECK is a compile-time directive as well but that's recent.

>2) require Foo;
>     is similar to:
>   eval `cat Foo.pm`;

It's actually significantly more complicated than that.  The three
things that leap to mind are:
1) It tracks if it's been loaded already and won't run it again if so.
2) It searches the @INC path for the file - under taint this won't
   include the current directory.
3) dies if Foo.pm doesn't return true at the end.  This is why you
   usually see 1; at the end of Perl modules.

Charles DeRykus, in an immanent manifestation of deity, wrote:
>use lib "/path/to/module";   # e.g.  use lib "C:/myhome/lib";
>use A;
>...

BTW, I've found that the FindBin module helps lots.  From the manpage:
        use FindBin;
        use lib "$FindBin::Bin/../lib";

This way you don't have to encode pathnames into your module.  If you
also used File::Path, your script would be highly transportable.

Darren
-- 
<torin at daft.com><http://www.daft.com/~torin/> <torin at debian.org><perl at slut.org>
Darren Stalder/2608 Second Ave, @282/Seattle, WA 98121-1212/USA/+1-206-ELF-LIPZ
@		     Make a little hot-tub in your soul.		      @

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
  Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/





More information about the spug-list mailing list