Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have an application where many of the modules can make sense on their own. I'd like to write each module as a perl program, and then include them in the main program via do or require (or another more or less equivalent statement). But if a module is called on its own, I'd like it to work on its own. Basically, I'm looking for a perl equivalent to python's if __name__ == '__main__': Suggestions?

Replies are listed 'Best First'.
Re: Detection of main script / libraries
by shmuelp (Initiate) on Mar 25, 2002 at 05:03 UTC

    The trick is to use the caller function. Example:

    a.pl: unless (caller[0] =~ /main/) { print "a was called directly\n"; }
    b.pl:do "a.pl";

    Now, if a.pl is called directly, it will print the message, but if b.pl is called first, and a.pl is called from b.pl, it will not print the message.

      As a concrete example of this:

      My::Standalone.pm
      unless (caller() =~ /main/) { My::Standalone->run(); } else { @My::Standalone::EXPORT = qw[run]; } package My::Standalone; use strict; use warnings; use Exporter; our @ISA = qw(Exporter); sub run { my($self) = shift || caller(); print "See, I do something\n"; } 1;

      You can then call this with any of the following:

      • perl My/Standalone.pm
      • perl -MMy::Standalone -e"run();"

      or include it in a script:

      test.pl
      #!perl use strict; use warnings; use My::Standalone; print "Do something\n"; run(); # Call the run function exit;
Re: Detection of main script / libraries
by strat (Canon) on Mar 25, 2002 at 12:14 UTC
    You could find the executed perl-Scriptpath with the module: FindBin:
    use FindBin (); # get actual path of this script print "Path of script is: $FindBin::Bin\n"; # no namespace pollution
    or just use: $0 for the filename.

    Otherwise, you could set a global Variable in the main-package (e.g. assign $0 to it) and ask it in every packages BEGIN-Block if it is already defined... Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

Re: Detection of main script / libraries
by Zaxo (Archbishop) on Mar 25, 2002 at 04:33 UTC

    I think __PACKAGE__ is what you want.

    $ perl -e'print __PACKAGE__,$/' main $

    After Compline,
    Zaxo

      __PACKAGE__ always prints out the current package, and in a script (that doesn't declare its own package) that has been included via "do" or "require", __PACKAGE__ still is "main". An inelegant solution is a create a global variable when the first script begins it's main path of execution, and check for that in each submodule. But the elegant way escapes me.
Re: Detection of main script / libraries
by hrakaroo (Initiate) on Mar 25, 2002 at 23:10 UTC
    Howdy, Okay, let me follow up a bit on my earlier response. Doing
    __FILE__ eq $0 and main();
    should work for what you are trying to do. This will tell you if the file (not the package) was executed directly. Your scripts will need to do:
    BEGIN { require "myfile" }
    before you can call any of the subroutines because
    use myfile;
    insists on slapping on the .pm extension.

    Cheers,
    Hrakaroo

Re: Detection of main script / libraries
by Anonymous Monk on Mar 25, 2002 at 22:35 UTC
    Try: __FILE__ eq $0 and main();