ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
12.3. Delaying use Until Run TimeProblemYou have a module that you don't need to load each time the program runs, or whose inclusion you wish to delay until after the program starts up. SolutionEither break up the DiscussionPrograms that check their arguments and abort with a usage message on error have no reason to load modules they'll never use. This delays the inevitable and annoys users. But those Here, an effective strategy is to place argument checking in a BEGIN { unless (@ARGV == 2 && (2 == grep {/^\d+$/} @ARGV)) { die "usage: $0 num1 num2\n"; } } use Some::Module; use More::Modules; A related situation arises in programs that don't always use the same set of modules every time they're run. For example, the factors program from Chapter 2, Numbers, needs the infinite precision arithmetic library only when the -b command-line flag is supplied. A if ($opt_b) { require Math::BigInt; } Because Math::BigInt is an object-oriented module instead of a traditional one, no import was needed. If you have an import list, specify it with a use Fcntl qw(O_EXCL O_CREAT O_RDWR); you might say this instead: require Fcntl; Fcntl->import(qw(O_EXCL O_CREAT O_RDWR)); Delaying the import until run time means that the rest of your program will not be subject to any imported semantic changes that the compiler would have seen if you'd used a You might want to encapsulate this delayed loading in a subroutine. The following deceptively simple approach does not work: sub load_module { require $_[0]; #WRONG import $_[0]; #WRONG } It fails for subtle reasons. Imagine calling A better implementation might look more like: load_module('Fcntl', qw(O_EXCL O_CREAT O_RDWR)); sub load_module { eval "require $_[0]"; die if $@; $_[0]->import(@_[1 .. $#_]); } But this still isn't perfectly correct in the general case. It really shouldn't import those symbols into its own package. It should put them into its caller's package. We could account for this, but the whole procedure is getting increasingly messy. A convenient alternative is the use autouse Fcntl => qw( O_EXCL() O_CREAT() O_RDWR() ); We put parentheses after Remember, too, that Read the See AlsoRecipe 12.2; the discussion on the |