| Subcribe via RSS

Perl Module Monday: Sub::Exporter

August 1st, 2011 Posted in CPAN, Perl

For this week’s entry, I’m taking a look at a module I first learned about in December  2009 while reading RJBS‘s Advent Calendar for that year: Sub::Exporter. I highly recommend his yearly calendar, as it is a great way to learn about new and interesting modules and features. Of course, it helps to actually use the things you find interesting: while I learned about this module over a year and a half ago, I’d completely forgotten about it until someone mentioned it during one of the talks as OSCON last week. Then I came across it in my notes on modules to consider for this series, and decided I’d best write about it soon, lest I forget it again!

Rather than going into an exhaustive explanation of what this module is, I invite you to take a quick look at the original advent calendar posting. Go ahead, I’ll wait. Done? Great!

Now, if you didn’t just check that out, or if you thought it was too long and just skimmed over it, here’s the short version: Sub::Exporter is a super-version of the core Exporter module. It allows other modules and scripts to import the routines you’ve chosen to export. But unlike Exporter, it gives both you and the user of your module a great range of flexibility in options and configuration of the routines that are exported/imported.

So, it can do everything that Exporter does, but it can also do a whole lot more. To me, the most useful feature of Sub::Exporter is the ability to rename an imported function when you import it. I have, in the past, had to opt to not import a given subroutine in order to avoid name-clashes between different modules. I would have to choose which one “wins”, and then use the full package name to call the other package’s routine. With Sub::Exporter, this is not only a fixable problem, it’s also the simplest of the examples of Sub::Exporter use.

The module is well-documented, coming not only with a basic manual page but also a tutorial page and a cookbook page. If only more modules did this! (I say that, but none of my modules do that, so I have no room to cast aspersions.) It is also fairly lightweight in both its own code and its dependencies (unlike last week’s PMM, which I later learned requires that you have Moose installed, even though it doesn’t use Moose directly).

I won’t necessarily replace all my usage of Exporter with Sub::Exporter— I think that some names are sufficiently unique as to avoid potential clashes— but I will certainly be using it in the future.

5 Responses to “Perl Module Monday: Sub::Exporter”

  1. Gabor SzaboNo Gravatar Says:

    I like your blogs and I like your PMM series!

    At first the fact that it is easy to import a module with a different name using Sub::Exporter sounded nice but then I thought about maintainability.
    I always suggest my customers to explicitly list the functions they are importing. That both reduces the chances of accidental collisions and IMHO a great way for documentation: The next person who will wonder where the ‘send’ function came from can just search the same file and find it. Of course if the renaming is visible in the same file then it might be just as good.

    Lastly I wonder, and I don’t criticize as it happens to me as well, if you think this is a useful module why don’t you use it? Isn’t that a sign that it “sound cool but not that useful?”. Is it just old fashioned inertia?

  2. Paul SeamonsNo Gravatar Says:

    *The* problem with Sub::Exporter is that it requires the module maintainer to use it. Obviously the vast majority of CPAN modules are not using Sub::Exporter. Sub::Exporter is useful, but Gabor pointed out this very problem – you are not using it, and I am not using it. It represents overhead in the name of convenience.

    Now there is a solution that turns the Sub::Exporter’s solution inside out (and I apologize because I am plugging a module that I happen to be the author of). A few years ago I encapsulated some much older logic into AutoRole. Much of the base functionality is similar to autouse (which I think is also an incredibly useful but poorly marketed module) – but it has some additional features. The relevant one looks like this:

    use AutoRole SomeModule => {foo => ‘my_foo’, bar => [‘bar’, ‘my_bar’]};

    You *can* import using just the same sub-names, but you can also alias to other names (multiple if you want).

    And for what its worth, I am in full agreement with Gabor that you should always be explicit in what you are importing.

  3. Ricardo SignesNo Gravatar Says:

    Sub::Import also provides a mechanism to use some of Sub::Exporter’s behaviors (literally, those from Sub::Exporter) on packages that only offer Exporter-style exporting.

  4. nadim khemirNo Gravatar Says:

    Well, i am using it and have been since 2007-01 which is the date of my short and rather unhelpful review. You just put it in whatever template you use to create modules and forget about it.

    As for declaring all the subs you are using, although I understand what you want to achieve, it seldom works because developers totally hate it when it is more than a sub or two. I am not against but I would like to see figures that support that, good but heavy, practice.

  5. ChipNo Gravatar Says:

    I’m rather fond of Exporter::Tidy. The interface is simple and neat. So far any missing features have not felt like problems.

Leave a Reply