Saturday, March 20, 2010

use vs require

Yes I know most places will tell you to do a use since that is the new way of doing things. But require still has it's uses and as long as you understand the differences you might choose to do a require over a use.

Lets start with the basics
require: Does the following at the point of execution
   * Takes as parameter a filename, a module or a version
   * If it is a filename - if a relative path or no path is provided loads relative to the current folder otherwise loads the filename provided into memory
   * If it is a module - traverses through @INC and tries to load the module into memory relative to the first folder where it can find the corresponding .pm file. Barewords are considered modules and :: are replaced with / for locating the file.
   * If it is a version - if it is a numeric throws an error if the perl version number stored in $] is less than this number or if it is a literal then $^V is compared and throws an exception if it is less than the required value.
   * If the file or module is found the content of the file is eval'd and throws an exception if it doesn't return true.

use:  Does the following at the point of being compiled
   * Takes as parameter a module, pragma or a version
   * If it is a module - traverses through @INC and tries to load the module into memory relative to the first folder where it can find the corresponding .pm file. In the module name :: are replaced with / for locating the file.
   * If it is a version - if it is a numeric throws an error if the perl version number stored in $] is less than this number or if it is a literal then $^V is compared and throws an exception if it is less than the required value.
   * If the module is found the content of the file is eval'd and throws an exception if it doesn't return true.
   * All exported items are imported into the current namespace


Now in most cases it makes sense to do a use rather than a require for the following reasons:
   * use would be applied at compile time and all syntax errors would be caught instantly
   * use only loads modules hence it forces you to create packages and ensures separate namespaces are created
   * use allows control over what symbol table entries are imported - in case of a require potentially everything could land in your namespace

There are few scenarios where require can provide benefit
   * Some modules import a lot of items into your namespace and do a lot of actions on being evaled - we would do a require only if this is an optional requirement
   * Some modules can be initialized only after some pre-processing has taken place. e.g. I have a common module for setting up log4perl but this can be initialized only after the command line parameters have been processed. This wont be possible if I do a use but require works perfectly for my needs.
   * To implement polymorphism where you require only the relevant modules and not the universe of all potential modules.


The bareword concept is elaborated below
   require Foo::Bar;    # a splendid bareword
   $class = 'Foo::Bar';
   require $class;      # $class is not a bareword
   require "Foo::Bar";  # not a bareword because of the ""
   eval "require $class"; # it is bareword again inside the eval

No comments:

Post a Comment

Followers