Chris Dolan wrote:
Advice? While this example is contrived, the "eval { require ... }"
idiom is used often in the wild, so this is not a wholly unrealistic
scenario.
Real-world example. SVN::Web uses this idiom to determine whether to
use CGI or CGI::Fast.
Even if CGI::Fast is installed it can still fail is FCGI.pm is missing.
Normally this isn't a problem, since if you're running as a CGI script
you only do this test once. The first time around trying to load
CGI::Fast it fails.
But... if you then think "Ah, I'll use HTTP::Server::Simple to provide
an easy way for people to test SVN::Web" then this doesn't work, as the
request triggered (that code's going away soon) a second C<require
CGI::Fast;> which succeeds.
To work around it you have to delete the relevant key from %INC if you
detect that the require failed the first time.
Here's an example (which assumes you have CGI::Fast installed, but not
one of its dependencies).
#!/usr/bin/perl
use strict;
use warnings;
my $r = 0;
foreach (1..2) {
foreach my $module (qw(CGI::Fast)) {
$r = eval "require $module;";
$r = 0 unless defined $r;
if($@ and $ARGV[0]) {
my $path = $module;
$path =~ s{::}{/}g;
$path .= '.pm';
delete $INC{$path};
}
print "$module: $r\n";
}
}
Run that and see:
CGI::Fast: 0
CGI::Fast: 1
indicating that the second time around the loop the 'require' worked.
Pass a true value as the first command line argument to exercise the
if() block, and see:
CGI::Fast: 0
CGI::Fast: 0
to force the second 'require' to fail.
N