The 2002 Perl Advent Calendar
[about] | [archives] | [contact] | [home]

On the 17th day of Advent my True Language brought to me..

I've been very serious this year, and I haven't chosen one Acme module yet for the calendar. Well, it's time to change that.

As you may already know, Acme modules represent the sillier side of Perl, the area of CPAN that's put aside for people to do odd things. The Acme namespace gives module authors a chance to show what can be done with new language concepts without being necessarily constrained by the actual rigours of trying to produce a genuinely useful module. It's the playground of Perl - and we all know how playing is an important part of learning.

Because playing is so important, I'm glad to present Acme::Intraweb, a module that will let you install whatever modules you need to run your script automatically.

There's not much to the description for today's entry. Using it is simplicity itself. All you need to do is use Acme::Intraweb before you use any module.

Let's demonstrate it's use with the File::Slurp module. On previous days I've been writing this code this to read in a whole file:

  use IO::File;
  my $fh = IO::File->new("filename","<")
    or die "Can't open 'filename': $!";
  my $data;
    local $/;         # set it to slurp the whole file
    $data = <$fh>;    # slurp!

Now if I have File::Slurp installed I can use one of the handy shortcut functions that it exports to do all that in one for me:

   use File::Slurp;
   my $data = read_file("filename");

The only trouble is that I can't guarantee it to be installed. However, if I install Acme::Intraweb then it'll all be installed automatically from the CPAN for me if it's not. Handy.

  use Acme::Intraweb;
  use File::Slurp;     # I haven't installed this yet 
  my $data = read_file("filename");

So when I execute the above and it runs the use File::Slurp and consequently realises that I don't have File::Slurp installed rather than dieing with an error it will attempt to install the File::Slurp module for me automatically. Excellent. However, on my system at least this will fail as as a normal user I don't have the rights on my system to install modules. I need to be running as root to do that.

One solution to this is to simply run the script as root. This is fine on my own box where if the code that I'm playing with goes awry and destroys some vital system files it's just me that's going to end up doing the reinstall. It's less good if I do it on a development box at work where my boss will be annoyed with me.

Rather than running the code What we really want to do is to tell Perl to just check the code as root.

  [root@gan] perl -c

The -c option tells perl that it should go though the compiling stage and detect any syntax errors in your code without actually running it. This is useful when debugging code in general - I can't tell you how many times running this on a CGI from the command line has caught a missing semicolon. In this particular case it's really useful to use the switch as in order to check for those syntax errors perl needs to load the modules that the script uses. As loading the modules triggers the automatic installation, simply running perl with the -c flag as root should be enough to automatically install the modules for you on most scripts. This technique may have some problems with scripts that load modules dynamically with require or string eval, but it should work on most scripts flawlessly.

While we're talking about command line switches, I should point out the -M switch that can be used from the command line to load a module before the main script is run. For example, we can use it to load the strict pragma on a script

  [mark@gan] perl -w -T -Mstrict

Using it with Acme::Intraweb means that we can run any script unaltered and have it automatically install the modules it requires.

  [root@gan] perl -MAcme::Intraweb -c

Now that is convenient.

  • File::Slurp
  • The Acme::* Modules - Leon's YAPC::Europe talk