[Canberra-pm] how to tell if a library is available?

Paul Fenwick pjf at perltraining.com.au
Tue Jun 17 01:39:28 PDT 2008


G'day Kim / p5p,

Kim Holburn wrote:

> It obviously works at run time as in the eval but what exactly it does  
> then I'm not sure.  I think from the behaviour I'm seeing that the use  
> in the eval is not determined at compile time because at compile time  
> it's just a string.  Therefore references to variables in the library  
> are not linked at compile time unless a naked "use" or "require"  
> statement appears somewhere.

Ah!  You may want something like this:

BEGIN {
	eval "use Text::Autoformat";
	if ($@) {
		# Holy smokes Batman!  Text::Autoformat isn't
		# available!  Do something to set up the variables,
		# subroutines, and other things that Text::Autoformat
		# would normally provide for us
	}
}

By wrapping the code inside a BEGIN block, you force it to be executed at 
compile-time, before Perl tries to resolve the rest of the subroutines and 
variables in your code.  If Text::Autoformat exists, then it gets loaded at 
compile time, and everything is fine.  If it doesn't exist, then you'll need 
to do *something* to ensure that parts of your code trying to use 
Text::Autoformat have something to play with.  I can't be more specific 
without seeing the warnings that's being generated; perhaps a piece of 
sample code may help here?

 > I guess what I'd like are some conditional compile directives but they
 > don't exist.

If you want code that's simply not compiled at all if a module isn't 
installed, you can do something like this:

BEGIN {	eval "use Text::Autoformat"; }

use constant AUTOFORMAT => $INC{'Text/Autoformat.pm'};

# Later, in your main code...

if (AUTOFORMAT) {
	# Do something that uses Text::AutoFormat...
} else {
	# Do something else.
}

What we're doing here is checking for the module at compile-time, setting a 
constant based upon whether it's been found and loaded, and then 
conditionally compiling code based upon that constant.  Because Perl knows 
that constants can't change, it can completely prune unwanted code from the 
parse tree at compile-time.  The text that was pruned won't give you 
warnings, because as far as Perl is concerned, it wasn't there. ;)

Of course, if you have to start pulling tricks like this, you'll probably 
find it becomes *much* easier to simply insist the modules you want are 
installed, or using PAR (the Perl Archiver) to bundle them up with your 
program.  You can find our tutorial on that at:

	http://perltraining.com.au/tips/2008-05-23.html

Cheerio,

	Paul

-- 
Paul Fenwick <pjf at perltraining.com.au> | http://perltraining.com.au/
Director of Training                   | Ph:  +61 3 9354 6001
Perl Training Australia                | Fax: +61 3 9354 2681


More information about the Canberra-pm mailing list