Perl 导出符号而不导出器

Perl 导出符号而不导出器,perl,Perl,我正在学习如何使用Perl中的包和对象 有人建议我使用Exporter,以便使用具有package指令的模块的函数和变量 我很想知道是否有一种不使用Exporter导出符号的方法?换句话说,Exporter可以以某种方式进行模拟吗 我之所以问这个问题,是因为我假设Exporter会为那些必须以尽可能快的速度运行的小而简单的脚本所不需要的功能带来额外的开销,并且可以通过将该功能包含在几行简单的代码中来避免 也许一个简单的说明我的意思会有所帮助 假设我有一个只做这个的模块 my $my_string

我正在学习如何使用Perl中的包和对象

有人建议我使用
Exporter
,以便使用具有
package
指令的模块的函数和变量

我很想知道是否有一种不使用
Exporter
导出符号的方法?换句话说,
Exporter
可以以某种方式进行模拟吗

我之所以问这个问题,是因为我假设Exporter会为那些必须以尽可能快的速度运行的小而简单的脚本所不需要的功能带来额外的开销,并且可以通过将该功能包含在几行简单的代码中来避免

也许一个简单的说明我的意思会有所帮助

假设我有一个只做这个的模块

my $my_string = "my_print";
sub my_print {
  print "$my_string: ", @_;
}
这将允许许多小脚本使用
my_print
而不是
print
,只需要一个简单的
require
和我模块的文件名(开销非常小)

然后,我想在另一个有包声明的模块中使用它,但它不再起作用,所以现在我必须在我的简单模块中使用
package
声明,因此
Exporter
,以便在新模块中使用它

使用Perl已经有一段时间了,我习惯于几乎所有的事情都非常简单、直接和低开销,所以我觉得可能会有这样的解决方案。如果不是,那么我会接受一个答案,确切地解释为什么出口商是唯一的方法。

绝对是低开销的。中还有一个替代模块列表

如果你很好奇,你可以为模块做一个简单的测试并查看自己。您会注意到,大多数“代码”只是文档。但是,老实说,如果您是perl新手,那么您不应该担心如何简化代码,使其重量尽可能轻,因为您应该尽可能多地利用资源,使编码更快、更容易


就我的.02美元

听起来很像是你在找借口逃避
出口商
?你是否真的有启动太慢的程序<代码>导出器仅在编译阶段加载和执行

如果您真的担心编译速度,那么您应该编写

BEGIN { require MyPackage }
后来

MyPackage::myprint($myparam)
这根本不涉及
导出器
的开销,甚至不涉及等效的在线代码

是的,实际上将符号从一个包导出到另一个包的代码只是
Exporter.pm
代码中的一行,您可以复制它。但是你不是更愿意加一句吗

use MyPackage;
在开始编程时,您是否知道,从任何上下文中,
MyPackage
中的符号都会正确导出


如果您有“必须尽可能快地运行的小型简单脚本”,那么您应该研究让它们作为守护进程运行,而不是在每次程序运行时重新编译Perl。

Exporter所做的事情非常简单。以下是不使用Exporter的方法:

在Foo.pm中:

package Foo;

use strict;
use warnings;

sub answer { 42 }

sub import {
  no strict 'refs';
  my $caller = caller;
  *{$caller . "::answer"} = \&answer;
}

1;
use Foo;

print answer(), "\n";
在script.pl中:

package Foo;

use strict;
use warnings;

sub answer { 42 }

sub import {
  no strict 'refs';
  my $caller = caller;
  *{$caller . "::answer"} = \&answer;
}

1;
use Foo;

print answer(), "\n";
然而,正如其他人所说,您真的不必担心使用Exporter的开销。它是一个相当小且高效的模块,从5.0开始就与Perl的每个版本捆绑在一起。此外,很可能您已经在某处加载了它——许多核心Perl模块(如Carp、Scalar::Util、List::Util等)都使用它


更新:在上面代码的早期版本中,我忘记了
没有严格的“refs”。这是
*{$some_string}
工作所必需的。

我对perl并不陌生,只是使用对象和包(不幸的是,我的问题被管理员编辑了,没有包括我添加的关于我为什么要问这个问题的一点解释)。但我肯定会研究Exporter的源代码,谢谢。这是为了让我更好地理解发生了什么以及为什么会这样,我还没有从我读过的所有文档中收集到一些东西。一般来说,如果每次我只想使用像“my_print”这样简单的东西时,我可以避免加载和编译另一个大文件(即,超过40行文本..再加上它可能需要的任何其他文件),我会这样做,即使实际开销不是那么大。这不仅仅是开销的问题。正如我之前的描述所述,这是我为了更好地理解遇到的一些问题而提出的一系列问题。使用
MyPackage::myprint($myparam)
不允许我用myprint替换
print
(也不允许我跨模块使用相同的$myu字符串),因此这不是一个可行的选择。在
BEGIN
块中使用
require
会不会导致所有
my
作用域变量被声明为仅限于该作用域而不是文件?在任何情况下,我的问题都是学习perl是如何做事情的(特别是在符号共享方面),学习更好的编程实践(并丢掉多年来学习的糟糕的编程实践)。。我不明白为什么这个问题必须被否决。@Inaser:如果你希望获得更好的编程实践,那么就使用Exporter。它的编写非常精确,因此它所包含的笨拙代码不必在每个需要该功能的程序中复制。@Inaser:不,您可以调用
MyPackage::myprint($myparam)
而不是将
myprint
导入本地包。此功能与导入
myprint
和写入
myprint($myparam)
的功能相同(尽管您的
myprint
不注意传递的任何参数),因此
$myparam
将被丢弃。它确实使用与
myprint
在同一个包中声明的
$myu字符串
。是的,在
BEGIN
块中声明的词法变量将仅限于该b