Also, useing a Perl file does not execute it,

This is SO wrong that I can't leave it uncommented, even if you intended to simplify.

AnomalousMonk++ already explained that used modules are evaluated.

To explain that a little bit more: use is an extended require happening at compile time, as if wrapped in a BEGIN block. (BTW: [doc://BEGIN] does not link properly.) require is an extended do FILENAME that prevents loading the same file more than once and checks the result of loading the file. This is why modules need to return a true value. And finally, do FILENAME behaves like an extended eval STRING, where the string is loaded from a file searched in @INC. All of this is documented in perlfunc.

But there is more:

Loading any module does not only parse the file and execute code outside the subroutine definitions. Modules can contain five different code blocks (BEGIN, UNITCHECK, CHECK, INIT, and END) that are executed outside the normal flow. Most notably, BEGIN blocks run while code is still being compiled; UNITCHECK and CHECK run after compilation, INIT runs before runtime, END after runtime. This is documented in perlmod.

Loading a module using the use function has yet another side effect, as documented in use:

[use Module LIST] is exactly equivalent to

BEGIN { require Module; Module->import( LIST ); }

So, in addition to the "magic" code blocks, a method in the module is invoked. (If the module has no import method, the one implicitly inherited from UNIVERSAL is invoked.) Again quoting use:

If you do not want to call the package's import method (for instance, to stop your namespace from being altered), explicitly supply the empty list:

use Module ();

That is exactly equivalent to

BEGIN { require Module }

So, loading a module using use, or even using require, actually runs a lot of code in that module:

demo.pl

#!/usr/bin/perl use strict; use warnings; BEGIN { print ">>> About to execute 'use LoadMe;' <<<\n"; } use LoadMe; BEGIN { print ">>> LoadMe was loaded <<<\n"; } print "***** See? No code in LoadMe is executed! *****\n";

LoadMe.pm

package LoadMe; use strict; use warnings; INIT { print "LoadMe: INIT is evaluated\n"; system "echo Would I run rm -rf / ?"; } CHECK { print "LoadMe: CHECK is evaluated\n"; system "echo Check check, is this thing on?"; } UNITCHECK { print "LoadMe: UNITCHECK is evaluated\n"; system "echo Luckily, format C: does not work on linux"; } BEGIN { print "LoadMe: BEGIN is evaluated\n"; system "echo what could go wrong?"; } END { print "LoadMe: END is evaluated\n"; system "echo Good bye cruel world"; } sub foo { print "LoadMe: foo\n"; } sub import { my $class=shift; print "LoadMe: import called as ${class}->import(",join(',',@_),") +\n"; system "echo Oh well, no smart comment here"; } print "LoadMe: Module initialisation\n"; system "echo Perl is fully working and can run arbitary code, includin +g external programs"; 1; # or any other non-false value

Demo:

/tmp/use-demo>perl demo.pl >>> About to execute 'use LoadMe;' <<< LoadMe: BEGIN is evaluated what could go wrong? LoadMe: UNITCHECK is evaluated Luckily, format C: does not work on linux LoadMe: Module initialisation Perl is fully working and can run arbitary code, including external pr +ograms LoadMe: import called as LoadMe->import() Oh well, no smart comment here >>> LoadMe was loaded <<< LoadMe: CHECK is evaluated Check check, is this thing on? LoadMe: INIT is evaluated Would I run rm -rf / ? ***** See? No code in LoadMe is executed! ***** LoadMe: END is evaluated Good bye cruel world /tmp/use-demo>

Another demo:

Perl has a -c switch, which has a nice, seemingly harmless first sentence in its documentation:

-c causes Perl to check the syntax of the program and then exit without executing it.

Except that this is completely wrong, as explained in the following sentence:

Actually, it will execute and BEGIN, UNITCHECK, or CHECK blocks and any use statements: these are considered as occurring outside the execution of your program. INIT and END blocks, however, will be skipped.

So what actually happens is that perl stops after the compile phase has completed, and instead of starting the run phase, it will print a success message unless the compile phase has failed.

This has consequences. Some code is even executed if you only intent to check the code:

/tmp/use-demo>perl -cw demo.pl >>> About to execute 'use LoadMe;' <<< LoadMe: BEGIN is evaluated what could go wrong? LoadMe: UNITCHECK is evaluated Luckily, format C: does not work on linux LoadMe: Module initialisation Perl is fully working and can run arbitary code, including external pr +ograms LoadMe: import called as LoadMe->import() Oh well, no smart comment here >>> LoadMe was loaded <<< LoadMe: CHECK is evaluated Check check, is this thing on? demo.pl syntax OK /tmp/use-demo>perl -cw LoadMe.pm LoadMe: BEGIN is evaluated what could go wrong? LoadMe: UNITCHECK is evaluated Luckily, format C: does not work on linux LoadMe: CHECK is evaluated Check check, is this thing on? LoadMe.pm syntax OK /tmp/use-demo>

Nothing of this is new (except for UNITCHECK, introduced in perl 5.10), but anyone should be aware of those features. Pretending that loading a module does not execute any code in the module does not help.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re^4: Using guards for script execution? by afoken
in thread Using guards for script execution? by R0b0t1

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.