Alternatively, you can use the if pragma (available in core since 5.6.2, a.k.a. forever):

use if $cond, "MyModule";
use if $cond, MyOtherMod => @import_args;

But: 1) you have to quote the module name (unless you use fat comma, like the second example); 2) you can’t specify minimum version; 3) you can’t do the equivalent of use MyModule () (avoiding calling import). And, the syntax is… well, suboptimal.

For completeness, you can also use eval "". The downsides: 1) you need to add or die to rethrow captured exception; 2) you need to express everything as a string, so if you import some data structure, you need to dump it as Perl first; 3) it’s slower (but most of the time it shouldn’t matter); 4) more importantly, you have to be more careful since it’s eval after all. So the usage of eval is not particularly attractive in this case.

Let’s face it, use is special and its specialness causes an annoyance if you want to emulate or “extend” it.

I’m thought-experimenting with a swiss-army-knife pragma for loading modules called module (not yet written). You still have to use use to get the compile-time access, it’s more verbose, and you still need to quote the module name, but the syntax is more regular and it’s open to future extension.