开发者

Perl: Check to see if your file was loaded as a module or run directly

How do I write a test in Perl to see if my file was run directly or imported from some other source? I'd like to do this to make it easy to bundle everything in one file but still writ开发者_高级运维e unit tests against the functions. My idea is to have something like this:

if (running_directly()) {
  main();
}

def main {
  this();
  that();
}

def this {
  # ...
}

def that {
  # ...
}

Then in a separate perl script I can load the original file and call this & that as unit tests.

I remember seeing this done before, but I can't remember how to do it. I'd like to avoid testing $0 against some known value, because that means the user can't rename the script.


First of all, Perl doesn't have a def keyword. :)

But you can check if a module is being executed directly or included elsewhere by doing this:

__PACKAGE__->main unless caller;

Since caller won't return anything if you're at the top of the call stack, but will if you're inside a use or require.

Some people have assigned the dreadful neologism "modulino" to this pattern, so use that as Google fuel.


You might be thinking of brian d foy's "modulino" recipe, which allows a file to be loaded either as a standalone script or as a module.

It is also described in greater depth in his "Scripts as Modules" article for The Perl Journal as well as "How a Script Becomes a Module" on Perlmonks.


See my related question about testing Perl scripts. You might also be interested in running a REPL with the module in question:

package REPL;

use Modern::Perl;
use Moose;

sub foo {
    return "foo";
}

sub run {
    use Devel::REPL;
    my $repl = new Devel::REPL;
    $repl->load_plugin($_) for qw/History LexEnv Refresh/;
    $repl->run;
}

run if not caller;

1;

And then on the command line:

$ perl REPL.pm
$ REPL->new->foo;
bar
^D
$ perl -MREPL -E "say REPL->new->foo"
bar
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜