Ah, after a bit of time, I realized the interplay here is more subtle than I was originally thinking.
My general rule is that, when loading a module conditionally, you have to work to avoid relying upon compile-time magic. The most obvious case of this would be to avoid code like:
if( $threads ) {
require threads::shared; threads::shared->import();
share @foo; # No parens used
}
Because the "share @foo;" line would cause a compile-time error (if you did 'use strict;') even when that line would never be run.
An even more glaring case is the compile-time magic of the \& sub prototype that allows:
use Exception::Spiffy 'catch';
catch {
...
};
For conditional usage, you'd need to do it more like:
require Exception::Spiffy; Exception::Spiffy->import('catch');
&catch( sub {
...
} );
But there is a more subtle interaction with the \[$@%] prototype of threads::shared::share(). For example, this code will likely work:
if( $threads ) {
require threads::shared; threads::shared->import();
share( \@foo );
}
But it also might not! If some module you loaded for whatever reason loaded something that loaded something that happened to load threads::shared, then that code would fail to compile, complaining:
Type of arg 1 to threads::shared::share must be one of [$@%] (not refe
+rence constructor)
So, to be sure your code will work, you need to write it as:
if( $threads ) {
require threads::shared; threads::shared->import();
&share( \@foo ); # The ampersand is important
}
|