22

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)

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Ville M
  • 2,009
  • 7
  • 30
  • 45

9 Answers9

24

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

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • 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 'links in bio' Ericson Apr 09 '09 at 00:09
  • 3
    How should I "load" the file? – Ville M Apr 09 '09 at 00:25
  • OK, got it, changed use to do. ie. do "mymod.pm"; – Ville M Apr 09 '09 at 00:36
  • @VilleM `require`! `do` will reload the module each time it's called. `require` only loads once. – Schwern Apr 09 '09 at 16:49
  • 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 Apr 09 '09 at 17:46
  • 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 Apr 09 '09 at 18:38
  • @Schwern: but reloading every time is what is wanted, given that it may be loading into different packages different times. – ysth Apr 12 '09 at 05:47
  • ysth, exactly, using do works perfectly now, thanks, this the accepted answer – Ville M Apr 16 '09 at 20:42
  • Old question, but curious - if you did want to keep the package, could you abuse `@ISA`? `package main; use Foo; @ISA = qw(Foo);`? – vol7ron Jun 06 '13 at 21:00
  • @vol7ron: `@ISA` lets you inherit methods, but you still can't call them as normal subroutines without the package specification. – brian d foy Jun 09 '13 at 22:40
  • @briandfoy that makes sense and it would only work for methods in the parent, that are not defined in main (child). Also learned that `use parent` is now preferred over `@ISA` - go figure :) – vol7ron Jun 10 '13 at 04:15
11

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 };
    }
}
jpalecek
  • 47,058
  • 7
  • 102
  • 144
Michael Carman
  • 30,628
  • 10
  • 74
  • 122
  • 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 Apr 09 '09 at 00:32
3

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
  • 64,182
  • 22
  • 135
  • 226
  • Great, exactly what I was hoping, no standard way in exporter I guess, but this definitely does what I need, thanks much – Ville M Apr 08 '09 at 23:14
  • 2
    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 Apr 08 '09 at 23:58
  • Could you elaborate on how to "walk through the symbol table"? – Ville M Apr 09 '09 at 00:02
  • 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 Apr 09 '09 at 00:13
  • 1
    Don't try to parse Perl code, /usr/bin/perl has already done that for you. – hillu Apr 09 '09 at 09:41
2

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

echo
  • 2,666
  • 1
  • 25
  • 17
2

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 'links in bio' Ericson
  • 20,880
  • 12
  • 98
  • 148
2

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
  • 96,171
  • 6
  • 121
  • 214
1

Although it is not usually wise to dump all subs from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Tero Niemi
  • 1,057
  • 11
  • 13
1

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()

case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

Sérgio
  • 6,966
  • 1
  • 48
  • 53
-1

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

Is there a way to "use" a single file that in turn uses multiple others in Perl?

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

Community
  • 1
  • 1
jrockway
  • 42,082
  • 9
  • 61
  • 86