Francesco wrote:
> Jenda Krynicky ha scritto:
>> From: sormariano <[EMAIL PROTECTED]>
>>   
>>> I made a script that uses some modules.
>>> Obviously if one of the modules is not installed, the script doesn't start.
>>> I'd like to have the possibility to notify to the user which are the 
>>> modules he still requires and that should have to be installed..
>>> I think I could wrote an "install script" that checks the modules 
>>> presence and if all it's ok, it starts the main script.
>>> So here I have several questions:
>>> 1) is this a good way to proceed ?
>>> 2) how could I check the module presence ?
>>> 3) Can I start the main script with a 'system mainscript.pl'
>>>     
>>
>> Put something like this on top of the script:
>>
>> BEGIN {
>>   push @INC, sub {print STDERR "Still looking for $_[1]\n";exit;};
>> }
>>
> I tried this and I got the following output
> 
> Still looking for Encode/ConfigLocal.pm
> 
> also if the modules were all installed.
> Moreover, it works fine if I insert a non existent module: e.g. I put as 
> first required module:
> use Tk2;
> and, correctly, your sulution says:
> Still looking for Tk2.pm
> 
> Could you explain to me what exactly your code does and why he looks for 
> Encode/ConfigLocal.pm ?

The end of Jenda's post, that you relegated to the end of this response, says 
this

Jenda wrote:
>
> You can of course not only inform the user, but also attempt to 
> install the module for him or something like that.
>
> See the "require" section in perldoc perlfunc, the "hooks".

And the text he refers to explains exactly how it works. The reason you get
Encode::ConfigLocal reported as missing is that the Encode module attempts to
require it, but encloses the require in an eval as it is quite happy if it is
not there. But the require has still failed and so is reported.

> About a check script as I said before, I wrote something like this
> ( please, don't blame me about the way to write perl: I'm a C programmer 
> in love with Perl since 2 years only :-D  )
> 
> #!/usr/bin/perl
> use File::Copy;
> use Test;
> 
> use strict;
> 
> $| = 1;
> 
> BEGIN { plan tests => 12 }
> 
> my @REQUIRED_MODULES = ( 'Tk',
>                          'DBD::SQLite',
>                          'MP3::Info',
>                          'Archive::Rar',
>                          'Archive::Zip' );
> my @NOTFOUND_MODULES = ();
> 
> my $warn = 0;
> my $str;
> 
> foreach my $module ( @REQUIRED_MODULES ) {
>     eval "require $module";
>     ok($@, '', "Error loading $module");
> 
>     if ( $@ ne '' ) {
>         push @NOTFOUND_MODULES, $module;
>         $warn++;
>     }
> }
> 
> foreach my $module ( @NOTFOUND_MODULES ) {
>     $str = $str . "Please, install [$module] module\n";
> }
> 
> if ( not $warn ) {
>     system ("./mainscript.pl");
> } else {
>     $str = $str . "\nCan't run mainscript\n";
>     system ( `kdialog --sorry "$str"`);
> }
> 
> 
> It works but I prefer to write all into 1 script.

I wasn't clear what your purpose was, as running a program will report any
module that is missing anyway. I can only guess that you want them all checkd in
one pass, and I have written this code that will do that for you. Just paste
this code right before any 'use MODULE' statements at the start of the program,
and if any fail to load it will die with a list of missing modules.

All it does is to put some stub code in place of any missing modules, with an
import routine that just pushes the name of the package onto array
@main::NOTFOUND. Then the CHECK block code just reports the contents of that
array and dies if it's not empty.

There are a number of issues with it, such as it only detecting missing modules
that have had their import routine called, but that's what use does anyway.
There are also probably others, but it's a start. See how you get on with it.

HTH,

Rob


use strict;
use warnings;

our @NOTFOUND;

BEGIN {
  push @INC, sub {

    my ($self, $package) = @_;
    $package =~ s#/#::#g;
    $package =~ s#\.pm$##;

    my $module = qq{
      package $package;
      sub import { push [EMAIL PROTECTED]::NOTFOUND, '$package'; }
      1;
    };

    open my $fh, '<', \$module;
    return $fh;
  }
}

CHECK {
  if (@NOTFOUND) {
    die "Modules not installed: ". join ', ', @NOTFOUND;
  }
}

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to