Use of Perl (), require (), do (),%inc and @INC

Source: Internet
Author: User
Tags eval hash naming convention relative require requires perl script
transferred from: http://perl.apache.org/docs/general/perl_reference/perl_reference.html Use (), require (), do (),%inc and @INC explained


The @INC array

@INC is a special Perl variable which is the equivalent of the shell ' s PATH variable. Whereas PATH contains a list of directories to search for executables, @INC contains a list of directories from which Perl Modules and libraries can be loaded.

When you use (), require () or does () a filename or a module, Perl gets a list of directories from the  @INC  varia BLE and searches them for the file it is requested to load. If the file, you want to load are not located in one of the listed directories, you have a to-tell Perl where to find the File. You can either provide a path relative to one of the directories in  @INC, or you can provide the full path to the FIL E.

 

the%inc hash

%inc is another special Perl variable that's used to cache the names of the files and the modules that were successfully Loaded and compiled by use (), require () or do () statements. Before attempting to load a file or a module with use () or require (), Perl checks whether it's already in the%inc hash. If it ' s there, the loading and therefore the compilation is not performed at all. Otherwise the file is loaded into memory and an attempt are made to compile it. Do () does unconditional loading--no lookup in the%inc hash is made.

If the file is successfully loaded and compiled, a new key-value pair are added to%inc. The key is the name of the that file or module as it was passed to the one of the three functions we have just mentioned, and I F It was found in any of the @INC directories except ".", "the value is the full path to the it in the file system.

The following examples would make it easier to understand the logic.

First, let's see what is the contents of @INC on my system:

  % 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. (current directory) was the last directory in the list.

Now let's load the module strict.pm and see the contents of%inc:

  % perl-e ' use strict; Print Map {"$_ = $INC {$_}\n"} keys%inc '
  
  strict.pm =/usr/lib/perl5/5.00503/strict.pm

Since strict.pm was found In/usr/lib/perl5/5.00503/directory and/usr/lib/perl5/5.00503/is a part of @INC,%inc include s the full path as the value for the key strict.pm.

Now let's create the simplest module in/tmp/test.pm:

  TEST.PM
  -------
  1;

It does nothing and 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. (The current directory), the relative path is inserted as the value. If we alter @INC, by Adding/tmp to the end:

  % 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 is found first relative to "." The directory/tmp was placed after. In the list. If we execute the same code from a different directory, the "." Directory won ' t match,

  % CD/
  % perl-e ' Begin{push @INC, "/tmp"} use test; \
  Print Map {"$_ = = $INC {$_}\n"} keys%inc '
  
  test.pm =& Gt /tmp/test.pm

So we get the full path. We can also prepend the path with Unshift (), so it would be a used for matching before "." and therefore we'll get the full Path as well:

  % 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 We BEGIN block and is the recommended approach.

These approaches to modifying @INC can is labor intensive, since if you want to move the script around in the File-system You had to modify the path. This can is painful, for example, when you move your scripts from development to a production server.

There is a module called Findbin which solves this problem in the plain Perl world, but unfortunately up untill Perl 5.9.1 It won ' t work under Mod_perl, since it's a module and as any module it's loaded only once. So the first script using it would have all the settings correct, but the rest of the scripts would not if located in a diff Erent directory from the first. Perl 5.9.1 provides a new function findbin::again which would do the right thing. Also the CPAN module Findbin::real provides a working alternative working under Mod_perl.

For the sake of completeness, I ll present the Findbin module anyway.

If You use the This module, you do not need to the 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 $FindBin:: Bin is equal to/tmp. If we move the script somewhere else ... e.g./tmp/new_dir in the code above $FindBin:: Bin equals/tmp/new_dir.

  %/tmp/load.pl
  
  test.pm =/tmp/test.pm

This was just like the use of Lib except that no hard coded path is required.

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 have a slight overhead because it would load from disk and recompile the Findbin module on each request. So it could be worth it.



Modules, Libraries and program Files

Before we proceed, let's define what we mean by module, the library and program file. Libraries

These is files which contain Perl subroutines and other code.

When these is used to break up a large program into manageable chunks they don ' t generally include a package declaration; When they is used as subroutine libraries they often do has a package declaration.

Their last statement returns True, a simple 1; statement ensures that.

They can named in any-desired, but generally their extension is. pl.

Examples:

  config.pl
  ----------
  # defaults to main::
  $dir = "/home/httpd/cgi-bin";
  $cgi = "/cgi-bin";
  1;

  mysubs.pl
  ----------
  # defaults to Main::
  sub print_header{
    print "content-type:text/ Plain\r\n\r\n ";
  }
  1;

  web.pl
  ------------Package
  web;
  # call like This:web::p rint_with_class (' Loud ', "Don t shout!");
  Sub print_with_class{
    my ($class, $text) = @_;
    Print Qq{<span class= "$class" > $text </span>};
  }
  1;
Modules

A file which contains Perl subroutines and other code.

It generally declares a package name at the beginning of it.

Modules is generally used either as function libraries (which. pl files is still but less commonly used for), or as Obje CT libraries where a module is used to define a class and its methods.

Its last statement returns TRUE.

The naming convention requires it to has a. pm extension.

Example:

  MYMODULE.PM
  -----------Package
  my::module;
  $My:: module::version = 0.01;
  
  Sub new{return bless {}, shift;}
  END {print "quitting\n"}
  1;
Program Files

Many Perl programs exist as a single file. Under Linux and other unix-like operating systems the file often have no suffix since the operating system can determine th At it's a Perl script from the first line (shebang line) or if it's Apache that executes the code, there is a variety of Ways to tell how and when the file should is executed. Under Windows a suffix is normally used, for example. pl or. plx.

The program file would normally require () any libraries and use () any modules it requires for execution.

It would contain Perl code but won ' t usually has any of the package names.

Its last statement may return anything or nothing.



require ()

Require () reads a file containing Perl code and compiles it. Before attempting to load the file it looks up the argument in%inc to see whether it has already been loaded. If it has, require () just returns without doing a thing. Otherwise An attempt is made to load and compile the file.

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 () would attempt to search for the file with all the directories listed in @INC. For example:

  Require "mylibs.pl";

If there is more than one occurrence of the file with the same name in the directories listed in @INC the first occurrence would be used.

The file must return TRUE as the last statement to indicate successful execution of any initialization code. Since never know what changes the file would go through in the future, you cannot be sure that the last statement would Always return TRUE. That's why the suggestion was to put "1;" At the end of file.

Although you should use the real filename to most files, if the file was a module, you could use the following convention in Stead:

  Require my::module;

This was 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, O R it didn ' t return TRUE, then the program would die (). To prevent the require () statement can is enclosed into a 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 "\nhello\n";

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 this program didn ' t die (), because Hello is printed. This trick was useful when you want to check whether a user have 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 "\nhello\n";

  %./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 are what you want on 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-to-pass a module to load was by its module name and not its filename. If the module is located in mycode.pm, the correct-to-use () it is:

  Use MyCode

And not:

  Use "mycode.pm"

Use () translates the passed argument to a file name replacing:: With the operating system ' s path separator (normally/) and appending. PM at the end. So My::module becomes my/module.pm.

Use () are exactly equivalent to:

BEGIN {require Module; Module->import (LIST); }

Internally it calls require () to do the loading and compilation chores. When require () finishes it job, import () is called unless () is the second argument. The following pairs is equivalent:

  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 @EXPORT to a list of tags to being exported by default. The module ' s manpage normally describes what tags is exported by default.

The second pair exports only the tags passed as arguments.

The third pair describes the case where the caller does isn't want any symbols to be imported.

Import () is not a builtin function, it's just an ordinary static method call into the "MyModule" package to tell the Modul E to import the list of features back into the current package. See the exporter manpage for more information.

When you write your own modules, always remember that it's better to use @EXPORT_OK instead of @EXPORT, since the former D OESN ' t export symbols unless it is asked to. Exports pollute the namespace of the module user. Also avoid short or common symbol names to reduce the risk of name clashes.

When functions and variables aren ' t exported you can still access them using their full names, like $My:: Module::bar or $M Y::module::foo (). By convention your can use a leading underscore on names to informally indicate that they is internal and not for public u Se.

There ' s a corresponding "no" command that un-imports symbols imported by use, i.e., it calls Module->unimport (LIST) INS Tead of import ().



Do ()

While does () behaves almost identically to require (), it reloads the file unconditionally. It doesn ' t check%inc to see whether the file was already loaded.

If do () cannot read the file, it returns UNDEF and sets $! To report the error. If do () can read the file but cannot compile it, it returns UNDEF and puts an error message in $@. If The file is successfully compiled, does () returns the value of the last expression evaluated.

Finish.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.