Gist of the Day: Perl require Versus use

So, way back when I used to be a guy who thought up interview questions for super-senior Perl developers. I actually developed quite the reputation for being a very effective first-round interview for senior Perlers. My interviews were perceived to be so tough that headhunters would debrief the candidates so they could create cheat-sheets. I never considered my interviews very difficult at all. Despite the fact that very few of the candidates passed my first round, none of these questions seemed very difficult to me. Mind you, the client I was interviewing for wasn’t looking for someone who was a good programmer, they were specifically looking for a good Perler (a very good Perler). It is important for interviewers to ask questions relevant to the job they are hiring for, and if you have a legacy application which is using a lot of the in-depth features of a language then that language may become something very important to your hiring.
This is one of those “gotcha” questions that I actually had a recruiter try to call BS on me with, and I think it’s a fundamental one since it really reflects whether or not you understand how modules work in Perl:

What is the difference between use and require in Perl?

There really are three key differences between the two statements:

  1. While require is evaluated at run-time, the use statement is evaluated at compile-time.
  2. With the use statement the import() method in the package you’re importing gets called while the same is not true for require statements.
  3. The usage for use allows only for a hard-coded package name while a require statement allows for variables and file names.

For item #3, since that’s a usage bit I won’t be covering it here.

The Demo

First, consider this Perl module:
[gist id=”6408129″ file=”UseOrRequire.pm”]
Now, here you can see I’ve defined five functions:

  1. INIT() – A special function in Perl which is called when compile is done and run-time is beginning. (This function is new as of Perl 5.10)
  2. BEGIN() – A special function in Perl which is executed as soon as possible, usually during the parsing of the module.
  3. END() – A special function in Perl which is executed as the module is leaving memory.
  4. say_hello() – A user-defined function which we will use in our demonstration.

Now let’s see how use works with this module:
[gist id=”6408129″ file=”perl_use_demo.pl”]
The output of this program is:

BEGIN CALLED!
import CALLED!
INIT CALLED!
hello! ./perl_use_demo.pl
Done.
END CALLED!

Here we can see that first BEGIN() is called. Following that, import() is called. From there we can see INIT() being called as we hand off to run-time. Then our program calls say_hello(), and then prints its own "Done." message. When we’re exiting we can see that END() is called.
Now let’s see how require is different:
[gist id=”6408129″ file=”perl_require_demo.pl”]
The output of this program is:

Too late to run INIT block at UseOrRequire.pm line 8.
BEGIN CALLED!
hello! ./perl_require_demo.pl
Done.
END CALLED!

The first thing we see here is a warning telling us that it’s too late to run INIT(). The reason for this is that require is evaluated at run-time, so the INIT() function – which is called at hand-off from compile-time to run-time – is never called because we missed the hand-off. This shows us that use really does evaluate at compile-time when require does only evaluate at run-time.
It is important also to notice that the import() call is not in our output. If you require a module you must call import() yourself (if you wish to call it).
I hope that this has helped you to better understand this difference in Perl. It’s a pretty material difference, and if you’re trying to troubleshoot issues with modules it is important to know this (especially if the problem you’re troubleshooting is related to performance or unimported symbols).
Here’s the full Gist: https://gist.github.com/manchicken/6408129

3 Replies to “Gist of the Day: Perl require Versus use”

  1. Very interesting, made me realize I’m not a “good” Perler (but I alredy suspected).
    I would like to ask, then, could you provide/ass some examples of when it’s good to use ‘require’ and when ‘use’ fits better ?
    Thanks in advance,

    Emanuele

  2. Any time you know you need a particular module, you can ‘use’ it.
    If you do not know until run-time which of several implementation modules you are going to use, you can ‘require’ it at run-time.
    For example, I wrote a system which evaluated stock market auctions. Some stock markets have an auction in the morning, some morning and afternoon, some even more often, some none at all. The details vary from market to market. I wrote an auction module, where you requested the auction data for a certain stock for a certain date, say, Evotec on the Stuttgart Boerse, by passing in its Name under the Reuters naming system, ‘evt.sg’, and the desired date.
    From the Reuters exchange name, ‘sg’, I knew you were asking for Stuttgart, so I would require the Stuttgart module, and then invoke certain routines to evaluate the auctions for the desired day.
    If I were to do that with ‘use’, I would load in several dozen modules, which would take longer than it was worth.
    Tom

  3. I think the most common example of the intentional use of `require` over `use` would be in use with Exporter.
    http://search.cpan.org/~toddr/Exporter-5.68/lib/Exporter.pm#SYNOPSIS
    The main reason to use `require` rather than `use` here is that if you set the inheritance tree to use `Exporter` (via @ISA, usually), then you will inherit the `import()` from the `Exporter` module, thus using its logic to import methods.
    While I agree with Tom’s suggestion of the use of `require`, I would clarify that `require` is not the only possible way to load modules during run-time. Another common strategy is to use a string eval. In this situation one would create a string such as `use $some_module_name` and then run it through the `eval()` function. This would spawn a sub-process to do all of the fun bits of loading the module. While that sounds slower, it really isn’t; require is essentially the same sort of task.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.