Built in Our Workshop, Delivered in Your Package
In Perl, we organize our subroutines (and other stuff) into namespaces called packages. This makes it easy to avoid having to think of unique names for functions you write, and it means you don't have thousands of core functions to remember. Traditionally, exports were provided by the Exporter module, included with
perl5 since its first release.
Now when someone says
use Gift::Dispatch ':all' the three exported routines become available in their package. This is a useful tool, and most Perl programmers interact with Exporter all the time. Unfortunately, it's not very flexible. For example, here's our attempt to use Gift::Dispatch:
Email::Send exports a
send routine by default, which will clobber the one from Gift::Dispatch. This is obviously a contrived example, but this problem happens in real life, too, and generally ends up being more obnoxious to track down. Subroutines installed by Exporter also stick around forever, so when somebody ends up trying to call
Gift::Giver->send, forgetting that the right method is
give, they get one of your imported routines instead of a "no such method" exception.
Sub::Exporter and Naming
Sub::Exporter (sometimes affectionately referred to as S'Ex) makes it easy to fix this problem. First, we update Gift::Dispatch:
And then we update Gift::Giver to muck around with the names (unrelated code omitted):
Sub::Exporter and Code Customization
We got to muck about with the names under which things are imported. This is only the tip of the iceberg. Sub::Exporter can let you customize not just the names of imported routines, but also other facets of their operation. For example, we might not want to require the "carrier" parameter for our shipment above, if we can provide a default. It's easy to let Sub::Exporter handle an import like this:
With arguments like that, we can build routines with built-in defaults, overridden behavior, and all kinds of customization, wrapped up in a simple name that we choose.
Over next few weeks, quite a few of the libraries that will be discussed will either use Sub::Exporter to provide exported functions or will use Sub::Exporter to provide powerful customizable interfaces. To really learn how these work, you should go to the Sub::Exporter::Tutorial, but here's a quick non-trivial sample using the canonical closure example of a "counter":
Then we put it to use...
Sub::Exporter is easier to use than Exporter and in its most trivial configuration provides much more utility. Learning how to make the most of Sub::Exporter can make very complex code generation quite simple and can reduce the amount of code you must write significantly.