7

I have many standalone scripts. The only thing they share, is that they use() a large set of CPAN modules (that each export several functions). I would like to centralize this list of modules. I found several methods. Which one is the best?

  1. I could create SharedModules.pm that imports everything and then manually exports everything to main:: using Exporter.

  2. I could create SharedModules.pm that starts with "package main;" so it will import directly into main::. It seems to work. Is it bad practice and why?

  3. I could require() a sharedmodules.pl that seems to import everything into main:: as well. I don't like this method as require() doesn't work that well under mod_perl.

Number two looks best to me, however I wonder why for example Modern::Perl doesn't work that way.

Edit: I figured this question has been asked before.

Community
  • 1
  • 1
Willem
  • 3,043
  • 2
  • 25
  • 37
  • Don't sweat it; that's why [dupes aren't all that bad.](http://blog.stackoverflow.com/2010/11/dr-strangedupe-or-how-i-learned-to-stop-worrying-and-love-duplication/) –  Feb 07 '11 at 15:36
  • 1
    Also see: [Toolkit](http://p3rl.org/Toolkit) – daxim Feb 07 '11 at 15:51
  • 1
    I just recently found [ToolSet](http://search.cpan.org/perldoc?ToolSet) -- it is possible to arrange modules for import easily. – bvr Feb 07 '11 at 18:04

5 Answers5

6

Maybe more flexible than putting everything into main namespace would be to import into caller's namespace. Something like this:

package SharedModules;

sub import {

    my $pkg = (caller())[0];
    eval <<"EOD";

package $pkg;

use List::Util;
use List::MoreUtils;

EOD

    die $@ if $@;
}

1;
bvr
  • 9,687
  • 22
  • 28
4

The problem with all three of your proposed solutions is that the module may be used from another module, in which case the symbols should be exported into the useing module's package, not into main.

bvr's solution of using caller to import things directly into that package is a major step in the right direction, but prevents the 'real' package from using use ShareableModules qw( foo bar baz); to selectively import only what it actually needs.

Unfortunately, preserving the ability to import selectively will require you to import all relevant symbols from the underlying modules and then re-export them from ShareableModules. You can't just delegate the import to each underlying module's import method (as Modern::Perl does) because import dies if it's asked for a symbol that isn't exported by that module. If that's not an issue, though, then Modern::Perl's way of doing it is probably the cleanest and simplest option.

Dave Sherohman
  • 45,363
  • 14
  • 64
  • 102
2

Using require is the most natural way to do this. Under mod_perl you may need to modify @INC during server startup.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
2

Maybe you want Toolkit.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
1

File import.pl:

require blah;  blah->import;
require blubb; blubb->import;

Skripts:

#!/usr/bin/perl
do 'import.pl'
...

Patrick

Patrick
  • 508
  • 2
  • 9