Perl 之 use(), require(), do(), %INC and @INC
转自:http://perl.apache.org/docs/general/perl_reference/perl_reference.html?use(),require(),do(),%INC and @INC ExplainedThe @INC array
When you use(),require() or do() a filename or a module,Perl gets a list of directories from the? The %INC hash
If the file is successfully loaded and compiled,a new key-value pair is added to? The following examples will make it easier to understand the logic. First,let's see what are the contents of? % perl -e 'print join "n",@INC' /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 . Notice the? Now let's load the module? % perl -e 'use strict; print map {"$_ => $INC{$_}n"} keys %INC' strict.pm => /usr/lib/perl5/5.00503/strict.pm Since? Now let's create the simplest module in? test.pm ------- 1; It does nothing,but returns a true value when loaded. Now let's load it in different ways: % cd /tmp % perl -e 'use test; print map {"$_ => $INC{$_}n"} keys %INC' test.pm => test.pm Since the file was found relative to? % cd /tmp % perl -e 'BEGIN{push @INC,"/tmp"} use test; print map {"$_ => $INC{$_}n"} keys %INC' test.pm => test.pm Here we still get the relative path,since the module was found first relative to? % cd / % perl -e 'BEGIN{push @INC,"/tmp"} use test; print map {"$_ => $INC{$_}n"} keys %INC' test.pm => /tmp/test.pm so we get the full path. We can also prepend the path with unshift(),so it will be used for matching before? % cd /tmp % perl -e 'BEGIN{unshift @INC,"/tmp"} use test; print map {"$_ => $INC{$_}n"} keys %INC' test.pm => /tmp/test.pm The code: BEGIN{unshift @INC,"/tmp"} can be replaced with the more elegant: use lib "/tmp"; Which is almost equivalent to our? These approaches to modifying? There is a module called? For the sake of completeness,I'll present the? If you use this module,you don't need to write a hard coded path. The following snippet does all the work for you (the file is?/tmp/load.pl): load.pl ------- #!/usr/bin/perl use FindBin (); use lib "$FindBin::Bin"; use test; print "test.pm => $INC{'test.pm'}n"; In the above example? % /tmp/load.pl test.pm => /tmp/test.pm This is just like? You can use this workaround to make it work under mod_perl. do 'FindBin.pm'; unshift @INC,"$FindBin::Bin"; require test; #maybe test::import( ... ) here if need to import stuff This has a slight overhead because it will load from disk and recompile the? Modules,Libraries and Program FilesBefore we proceed,let's define what we mean by?module,?library?and?program file.
require()require() reads a file containing Perl code and compiles it. Before attempting to load the file it looks up the argument in? require() has to find the file it has to load. If the argument is a full path to the file,it just tries to read it. For example: require "/home/httpd/perl/mylibs.pl"; If the path is relative,require() will attempt to search for the file in all the directories listed in? require "mylibs.pl"; If there is more than one occurrence of the file with the same name in the directories listed in? The file must return?TRUE?as the last statement to indicate successful execution of any initialization code. Since you never know what changes the file will go through in the future,you cannot be sure that the last statement will always return?TRUE. That's why the suggestion is to put " Although you should use the real filename for most files,if the file is a?module,you may use the following convention instead: require My::Module; This is equal to: require "My/Module.pm"; If require() fails to load the file,either because it couldn't find the file in question or the code failed to compile,or it didn't return?TRUE,then the program would die(). To prevent this the require() statement can be enclosed into an eval() exception-handling block,as in this example: require.pl ---------- #!/usr/bin/perl -w eval { require "/file/that/does/not/exists"}; if ($@) { print "Failed to load,because : $@" } print "nHellon"; When we execute the program: % ./require.pl Failed to load,because : Can't locate /file/that/does/not/exists in @INC (@INC contains: /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 .) at require.pl line 3. Hello We see that the program didn't die(),because?Hello?was printed. This?trick?is useful when you want to check whether a user has some module installed,but if she hasn't it's not critical,perhaps the program can run without this module with reduced functionality. If we remove the eval() part and try again: require.pl ---------- #!/usr/bin/perl -w require "/file/that/does/not/exists"; print "nHellon"; % ./require1.pl Can't locate /file/that/does/not/exists in @INC (@INC contains: /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 .) at require1.pl line 3. The program just die()s in the last example,which is what you want in most cases. For more information refer to the perlfunc manpage. use()use(),just like require(),loads and compiles files containing Perl code,but it works with?modules?only and is executed at compile time. The only way to pass a module to load is by its module name and not its filename. If the module is located in?MyCode.pm,the correct way to use() it is: use MyCode and not: use "MyCode.pm" use() translates the passed argument into a file name replacing? use() is exactly equivalent to: BEGIN { require Module; Module->import(LIST); } Internally it calls require() to do the loading and compilation chores. When require() finishes its job,import() is called unless? use MyModule; BEGIN {require MyModule; MyModule->import; } use MyModule qw(foo bar); BEGIN {require MyModule; MyModule->import("foo","bar"); } use MyModule (); BEGIN {require MyModule; } The first pair exports the default tags. This happens if the module sets? The second pair exports only the tags passed as arguments. The third pair describes the case where the caller does not want any symbols to be imported.
When you write your own modules,always remember that it's better to use? When functions and variables aren't exported you can still access them using their full names,like? There's a corresponding " do()While do() behaves almost identically to require(),it reloads the file unconditionally. It doesn't check? If do() cannot read the file,it returns? ? 完! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |