views:

992

answers:

6

I would like to expose all subs into my namespace without having to list them one at a time:

@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

+1  A: 

You can always call subroutines in there fully-specified form:

MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

Jon Ericson
Yes, I am aware of that, but how about not having to say MyModule:: for every sub? I am looking for EXPORT ALL?
Ville M
@Ville M: It's often hard to know what someone else is aware of if they don't say it. ;-)
Jon Ericson
Something about sound and tree falling in the forest comes to mind... anyway, thanks for your help
Ville M
A: 

You will have to do some typeglob munging. I describe something similar here:

http://stackoverflow.com/questions/437785/is-there-a-way-to-use-a-single-file-that-in-turn-uses-multiple-others-in-perl/437835#437835

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

jrockway
A: 

Warning, the code following is as bad an idea as exporting everything:

package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux
Chas. Owens
Great, exactly what I was hoping, no standard way in exporter I guess, but this definitely does what I need, thanks much
Ville M
I think I'd just walk through the symbol table and look for defined code entries. There are too many ways that regex can fail.
brian d foy
Could you elaborate on how to "walk through the symbol table"?
Ville M
Yep, that is why I put the caveat on there that it was a bad idea. It was just the easiest way I could think of and if it causes problems, well, it shouldn't have been done in the first place.
Chas. Owens
Michael Carman's answer shows what I was talking about.
brian d foy
Don't try to parse Perl code, /usr/bin/perl has already done that for you.
hillu
+8  A: 

Don't do any exporting at all, and don't declare a package name in your library. Just load the file and everything will be in the current package. Easy peasy.

brian d foy
Excellent answer!
Ville M
Doh! I tap-danced all around that solution without thinking about it. (But it does break the expectation that a module will have it's own namespace, which can surprise.)
Jon Ericson
How should I "load" the file?
Ville M
OK, got it, changed use to do. ie. do "mymod.pm";
Ville M
@VilleM `require`! `do` will reload the module each time it's called. `require` only loads once.
Schwern
Interesting, thanks.
Ville M
hmm, changing do to require doesn't work for some reason: ".pm did not return a true value at modtest.pl line 2"
Ville M
That's an easy fix. Return a true value at the end of modtest.pl. That's why you see a lot of Perl modules ending in `1;`
brian d foy
@Schwern: but reloading every time is what is wanted, given that it may be loading into different packages different times.
ysth
ysth, exactly, using do works perfectly now, thanks, this the accepted answer
Ville M
+3  A: 

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.

# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
     next if      $name eq 'BEGIN';   # don't export BEGIN blocks
     next if      $name eq 'import';  # don't export this sub
     next unless *{$symbol}{CODE};    # export subs only

     my $imported = $caller . '::' . $name;
     *{ $imported } = \*{ $symbol };
    }
}
Michael Carman
Also see Leon's answer in http://stackoverflow.com/questions/607282/whats-the-best-way-to-discover-all-subroutines-a-perl-module-has
brian d foy
+2  A: 

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

ysth
was this what you were thinking of? http://search.cpan.org/dist/Exporter-NoWork/lib/Exporter/NoWork.pm
Chas. Owens
@Chas. Owens - no, I was thinking of Exporter::Simple
ysth