Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re: announce missing modules

by jasonk (Parson)
on Feb 23, 2008 at 17:29 UTC ( #669758=note: print w/replies, xml ) Need Help??

in reply to announce missing modules

You can put code refs in @INC, which means you could do this automatically, rather than having to wrap your list of modules...

package MissingModules; my %missing = (); BEGIN { push( @INC, sub { my ( $code, $mod ) = @_; $mod =~ s#/#::#g; $mod =~ s/\.pm$//; $missing{ $mod }++; open( my $fh, '+>', undef ); print {$fh} "package $mod;\n1;\n"; seek( $fh, 0, 0 ); return $fh; } ); } INIT { if ( my @list = keys %missing ) { warn "Please install CPAN modules: cpan -i @list\n"; exit; } } 1;

Then in your other code:

#!/usr/bin/perl use MissingModules; use CGI; use Foo; use Bar; use Baz; 1;

When you run it, you will get...

% perl Please install CPAN modules: cpan -i Bar Baz Foo

We're not surrounded, we're in a target-rich environment!

Replies are listed 'Best First'.
Re^2: announce missing modules
by Arif (Acolyte) on Feb 24, 2008 at 17:40 UTC
    That's a great idea. I started to play with something similar and got the following for the anon function on the @INC array.
    BEGIN { use 5.8.0; use vars qw(@missing); push @INC, sub { my ($coderef, $filename) = @_; # Ignore non-modules. return undef unless ($filename =~ s/.pm$//); # Remember the module. $filename =~ s/\//::/g; push @missing, $filename; # Return a dummy file handle. open my $FH, '<', \'1;'; $FH; }; }
    The INIT block is a great idea.
    INIT { # Check and clean up. die "Missing modules.\n\tcpan -i ", join(' ',' @missing), "\n\ +n" if (@missing); pop @INC; }
    The open my $FH, '<', \'1;'; is available in perl 5.8.8.

    Is there a better way to deduce the module name than removing the .pm extension and replacing /s with ::? Will it work on non-UNIX platforms?

    Popping the function off again seems like a good idea.

      Just for the record, I found the flaw in this scheme. One of my included modules includes 'Storable', which tries to include 'Log::Agent'. If it fails then the 'Storable' module does something else. The above @INC scheme forces the user to install the conditional module. This shouldn't happen.

      So back to the old method (slightly refined to handle module versions and import lists)

      { our @missing = map +(m/^(\S+)/), grep !eval "use $_; 1", grep $_, split /\s*\n\s*/, " Storable File::Basename A::B wq(a b c) Foo::Bar CGI qw/:standard/ " and die "Please install CPAN modules: cpan -i @missing\n"; }

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://669758]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2021-10-19 22:08 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (77 votes). Check out past polls.