hellkat has asked for the wisdom of the Perl Monks concerning the following question:

Hi-

I would like to print an error message in my program that takes command line arguments if the user gives a particular argument, but the system the script lives on does not contain the modules used to run that section.

My program works at not 'require'ing the module if the argument is not given, but when I do give the option and the modules are not installed on that system, it just doesn't print the error message that I want, it prints the standard perl "Can't locate XXX in @INC"

I have tried the following and all do not work:
require XXX or die "my error message";
require XXX || die "my error message";
die "my error message" unless require XXX;
if (! require XXX) { die "my error message" }

I was streatching on the last one, but I figured it was worth a shot. And I know the first 2 are functionally equivalent.

I've thumbed through my books and nada. Any help would be great.

Replies are listed 'Best First'.
Re: error message if module doesn't exist?
by dkubb (Deacon) on Jan 16, 2001 at 07:52 UTC
    The following code should allow you to load in modules, on the fly, and handle exceptions if they are not found in the @INC path:
    #Can we load Module.pm? if(eval q{ require Module }) { #Yes, found Module.pm in @INC #Make sure you explicitly call it's import() routine Module->import; print 'Found Module'; } else { #No, Module.pm is not in @INC, die with a stacktrace croak 'Could not locate Module in @INC'; }
      The q{} is misleading there. This comes closer:
      BEGIN { if (eval { require Module }) { Module->import(qw(whatever you wanted here)); } else { die "with a different message, is that what this is all about? yu +ck"; } }
      It's important to do it within a BEGIN so that it has a chance to set up prototypes and identify subroutines for non-paren invocations.

      -- Randal L. Schwartz, Perl hacker

        Good point on not needing quoting for the eval.

        But no, you don't want the BEGIN in this case. The module won't be required unless a certain option is specified on the command line. So the code must compile even without the module so you can't write the code such that it makes use of prototypes or predeclaration of subroutines (unless you want to duplicate those predeclarations in your code).

        So you want something like:

        if( need_module_X() ) { if( ! eval { require Module::X; 1 } ) { die "You can't use feature X because Module::X is not installe +d.\n"; } else { Module::X->import( qw( A B C ) ); } }
        Note that I added "; 1" because I don't care to memorize or rely on which statements return a true value on success. Note that you can still import routines so that you can call them via A() instead of Module::X::A().

        If you do want/need prototypes or predeclaration of subroutines, then you could consider using autouse, though that doesn't give you the custom error message. Otherwise it would look something like:

        BEGIN { if( ! eval { require Module::X; 1 } ) { die "You can't use feature X because Module::X is not installe +d.\n" if need_module_X(); sub A { croak "Not available" }; sub B(\%); *B= \&A; sub C(); *C= \&A; } else { Module::X->import( qw( A B C ) ); } }
        Untested and unliked. (:

                - tye (but my friends call me "Tye")
Re: error message if module doesn't exist?
by AgentM (Curate) on Jan 16, 2001 at 04:52 UTC
    Two solutions: (1) Wrap it in an if/eval line. (2) Check the path yourself before requiring it using -e. Also, don't forget to import modules after you require them for dynamic-linked-type access.
    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.