我想将所有sub公开到我的命名空间中,而不必一次列出一个:
@EXPORT = qw( firstsub secondsub third sub etc );
使用完全限定名称需要对现有代码进行大量更改,因此我宁愿不这样做。
是否有@EXPORT_ALL?
我认为文档说这是一个坏主意,但无论如何我还是想这样做,或者至少知道如何。
回答Jon的原因:现在为了快速重构,我想将一堆sub转移到他们自己的包中,对现有脚本进行最少的麻烦和代码更改(这些子当前使用并经常重复)。
另外,大多数情况下,我只是好奇。 (因为看起来出口商似乎也可以将其作为标准功能,但到目前为止它基于答案有点令人惊讶,但它没有)
答案 0 :(得分:23)
根本不要进行任何导出,也不要在库中声明包名。只需使用require
加载文件,一切都将在当前包中。容易腻。
答案 1 :(得分:10)
别。但是如果你真的想...编写一个自定义import
,它会遍历符号表并导出所有已命名的子程序。
# 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 };
}
}
答案 2 :(得分:3)
警告,以下代码与导出所有内容一样糟糕:
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__
以下是使用该模块的一些代码:
#!/usr/bin/perl
use strict;
use warnings;
use Expo;
print map { "[$_]\n" } @Expo::EXPORT;
foo("foo");
bar("bar");
baz("baz");
quux("quux");
这是它的输出:
[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux
答案 3 :(得分:2)
您始终可以使用完全指定的格式调用子例程:
MyModule::firstsub();
对于我在内部编写的模块,我发现这个约定非常有效。这是更多的打字,但往往是更好的文档。
请查看perldoc perlmod
,了解有关您要完成的工作的更多信息。
更一般地说,您可以查看Exporter
的代码,看看它是如何使用全局别名的。或者,您可以检查模块的命名空间并导出每个子例程。 (我不想在此刻搜索如何执行此操作,但Perl使这相当容易。)或者您可以将子例程放在main
包中:
package main;
sub firstsub() { ... }
(我认为这不是一个好主意,但你知道的比我想做的更好。)
这样做提供没有任何问题你知道自己在做什么,而不只是试图避免考虑你与外界的接口。
答案 4 :(得分:2)
也许您会对CPAN上的一个Export *模块感兴趣,只需在子定义中添加一个属性,就可以将subs标记为可导出? (不记得是哪一个。)
答案 5 :(得分:2)
https://metacpan.org/pod/Exporter::Auto
导出:自动。这就是你所需要的一切。
答案 6 :(得分:1)
虽然将所有sub
从模块转储到调用者名称空间通常并不明智,但有时会自动生成@EXPORT_OK
和%EXPORT_TAGS
个变量(并且更干!)
最简单的方法是扩展Exporter。一个简单的例子是这样的:
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;
请注意使用goto
将我们从调用者堆栈中删除。
可在此处找到更完整的示例:http://pastebin.com/Z1QWzcpZ它会自动从子例程前缀生成标记组。
答案 7 :(得分:1)
图书馆是:
package mycommon;
use strict;
use warnings;
sub onefunctionthatyoumadeonlibary() {
}
1;
你可以使用它,调用common :::
#!/usr/bin/perl
use strict;
use warnings;
use mycommon;
common::onefunctionthatyoumadeonlibary()
图书馆,你可以轻松导出它们:
package mycommon;
use strict;
use warnings;
use base 'Exporter';
our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;
在相同的“命名空间”中使用它:
#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);
onefunctionthatyoumadeonlibary()
我们也可以混合使用这两种情况,我们可以导出更常用的函数来使用它,而无需调用包名称和其他函数,我们只用包名称调用它们,而不需要导出它们。
答案 8 :(得分:-1)
你将不得不做一些类型的改变。我在这里描述类似的东西:
Is there a way to "use" a single file that in turn uses multiple others in Perl?
那里的导入例程应该完全符合你的要求 - 只是不要将任何符号导入你自己的命名空间。