Gossamer Forum
Home : General : Perl Programming :

Conditional inline use of use

Quote Reply
Conditional inline use of use
Is it possible to have a 'use' statement as conditional?

For example, rather than calling use Image::Magick; at the top of a .pm file, I want to include
it in the code, so that it is only included when/if the specific code gets executed.
Code:
if ($mode eq 'IM') {

use Image::Magick;

print $IN->header (-type=>'image/png', -cookie => $cookie);
}
else {
print $IN->header (-cookie => $cookie);
}

The problem I have is that when the code above is installed as a plugin for LinksSQL,
it generates an error if Image::Magick is not installed. Even if 'mode' is not 'IM'.

In other words, I have several 'modes' that I would like to use for creating an image.
The admin specifies the 'mode' to use via setup, i.e. IM for Image::Magick, GD for GD::Image, etc...
Then I call the script which should include the necessary module based on 'mode',
and ignore the other modules.

Additionally is there a way to check if a perl module is installed without
interupting the scripts execution?

If so, I could have the admin select a Perl Module to use for image creation
during the installation of the plugin, and install only the code that uses that module.
I would want to give them a dropdown menu of installed choices.

Any pointers/suggestions are appreciated.

Thank you,
Chris
RGB World, Inc. - Software & Web Development.
rgbworld.com
Quote Reply
Re: [rgbworld] Conditional inline use of use In reply to
use 'require' instead of 'use', and enclose it inside an 'eval' block.

Code:
eval { require Image::Magick }

For example, in one of my plugins, I use the following code:

Code:
sub pre_install {
# -----------------------------------------------------------------------------
# This function displays an HTML formatted message that will display any
# instructions/information to the user before they install the plugin.
#
my $hasXML = eval { require XML::Simple } ? "pass" : '<font color="red">fail</font>';
my $hasHTML = eval { require HTML::TokeParser } ? "pass" : '<font color="red">fail</font>';

my $inst_msg = <<END_OF_HTML;
Required modules: <br />
<ul>
<li>XML::Simple -> $hasXML</li>
<li>HTML::TokeParser -> $hasHTML</li>
</ul>
<br />
Required update for GT::CGI:<br />
<br />
<a href="http://www.gossamer-threads.com/perl/gforum/gforum.cgi?post=292660">Go here for details.</a><br />
<br />
Please ensure the above prerequisites are installed before continuing.
END_OF_HTML

return $inst_msg;
}

Philip
------------------
Limecat is not pleased.
Quote Reply
Re: [rgbworld] Conditional inline use of use In reply to
There are a few options. Because 'use's are evaluated at compile time, that is not what you want (even in a case like use Some::Module if 0, perl will try to 'use' Some::Module). The alternatives are using 'use' in an 'eval', 'require'ing the modules you need, or 'do'ing them. With 'use' and 'require', your program will croak if the module is not available. With 'do', you will instead get undef ($! is set if the file could not be read, $@ is set if it could not be compiled, otherwise, 'do' returns the value of the last expression evaluated).

If is important to note that
Code:
use Module (@list);


is exactly the same as
Code:
BEGIN {
require Module;
import Module (@list);
}


. You can put your own solutions in a 'BEGIN' block as well, but I don't recommend putting any programatic aspected in 'BEGIN'. In one program I wrote, there are hundreds of code files, and which will be included depends on certain variables. So (in order to get the benefits of prototyping) I parse settings files and include files (using 'do'; a failure results in the controlling variables being changed) within a 'BEGIN'.

Last edited by:

mkp: Sep 7, 2006, 10:12 AM
Quote Reply
Re: [mkp] Conditional inline use of use In reply to
Thanks for the tip. Using 'use' in an 'eval' did the trick with my setup:

Code:

$module[10] = "Combo::Standard";
$module[13] = "CTS::Standard";
$module[16] = "Tax_P::Standard";
$module[15] = "Tax_Q::Standard";

#---------------------------------------------------------------------------------------------
sub validate_file()
#---------------------------------------------------------------------------------------------
{
my $obj = undef;
if (defined $module[$fileSpecID]) {
eval "use $module[$fileSpecID]";
die "couldn't load module : $!n" if ($@);
$obj = new Standard;
return $obj->ValidateImportFile();
}
else {
return 0;
}
}