http://qs321.pair.com?node_id=239078

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

Fellow monks,

How do I write code that uses modules if they are available? I am developing a solution for websphere mq, but not all customers will use it. However, if I say "use MQSeries;", I get a compile error unless mq is installed on that machine. So - stick the use clauses inside a string eval, or do you have a more elegant solution?

Replies are listed 'Best First'.
Re: Optional modules?
by tachyon (Chancellor) on Feb 27, 2003 at 12:56 UTC

    Nope.

    my $ne_loaded = 1; eval "use Non::Existent"; if ($@) { warn "You don't have Non::Existent installed so..."; $ne_loaded = 0; }

    That is the easy part. You obviously need to use the flag in response to missing module so your code does not try to call missing routines at runtime.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Optional modules?
by broquaint (Abbot) on Feb 27, 2003 at 13:06 UTC
    eval { require MQSeries; MQSeries->import; }; $@ and warn $@;
    So that will attempt to 'use' MQSeries and warn if it fails. Or as a subroutine
    sub cond_use { (my $module = shift().".pm") =~ s<::></>g; eval { require $module; $module->import(@_); }; $@ and warn $@; } cond_use "MQSeries";

    HTH

    _________
    broquaint

Re: Optional modules?
by castaway (Parson) on Feb 27, 2003 at 12:54 UTC
    The accepted solution seems to be to use eval with require (You can't do a 'use' inside an 'eval').
    my $loaded; { # ignore warnings if subs are being redefined local $^W = 0; $loaded = eval "require MQSeries"; } if(!defined($loaded)) { print "Can't load MQSeries: $@\n"; }
    Note: you'll need an 'import' in there if you also want to import exported methods etc.

    update: Apparently 'use' does work in 'eval', I can't for the life of me remember why I thought you can't, must have been some reason that I use require.. hohum..

    C.

      You can't do a 'use' inside and 'eval'

      eval "use CGI"; $q = new CGI; print $q->header; __DATA__ Content-Type: text/html; charset=ISO-8859-1
      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Optional modules?
by crouchingpenguin (Priest) on Feb 27, 2003 at 14:37 UTC

    To add on to the suggestions above, I would also put it all in a BEGIN block.

    #!/usr/bin/perl use strict; use warnings; use vars qw( $ne_loaded ); + BEGIN { eval "use Non::Existent"; if ($@) { warn "You don't have Non::Existent installed so..."; $ne_loaded = 0; } }

    cp
    ---
    "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."