以类似Python的Perl导入';导入为';

以类似Python的Perl导入';导入为';,perl,Perl,Perl是否有类似python的导入为 如果模块没有指定包,那么这个黑客小解决方案可以工作: # mod1.pm sub routine{ return "I'm from mod1\n"; } 如果模块具有自己的名称空间,则这不起作用: # ABC.pm package ABC; sub routine{ return "I'm from ABC\n"; } 是否可以导入文件,并将其内容强制放入特定的命名空间?如果要加载DEF.pm并以bar访问它,可以通过typeglob执行此操

Perl是否有类似python的
导入为

如果模块没有指定包,那么这个黑客小解决方案可以工作:

# mod1.pm
sub routine{ return "I'm from mod1\n"; }

如果模块具有自己的名称空间,则这不起作用:

# ABC.pm
package ABC;
sub routine{ return "I'm from ABC\n"; }


是否可以导入文件,并将其内容强制放入特定的命名空间?

如果要加载
DEF.pm
并以
bar
访问它,可以通过typeglob执行此操作:

这将适用于包中的单个子包,以更改符号表

但我会问你为什么要这么做?你有两个互相冲突的名称空间吗?这是一个让代码更混乱而不是更干净的好方法,所以我一般不认为这是一个好主意

否则-您可以使用代码引用:

my $ref_to_routine = \&DEF::routine;

$ref_to_routine->();
&$ref_to_routine();

您的模块实际上不导出任何内容

ABC.pm

package ABC;
use Exporter qw( import );
our @EXPORT = qw( routine );
sub routine { return __PACKAGE__ }
package DEF;
use Exporter qw( import );
our @EXPORT_OK = qw( routine );
sub routine { return __PACKAGE__ }
DEF.pm

package ABC;
use Exporter qw( import );
our @EXPORT = qw( routine );
sub routine { return __PACKAGE__ }
package DEF;
use Exporter qw( import );
our @EXPORT_OK = qw( routine );
sub routine { return __PACKAGE__ }
脚本

package foo;
use ABC qw( routine );

package bar;
use DEF qw( routine );

package main;
print foo::routine(), "\n";   # ABC
print bar::routine(), "\n";   # DEF
您还可以使用类似以下内容:

use ABC qw( );
use DEF qw( );
BEGIN {
   *foo_routine = \&ABC::routine;   # Could use foo::routine if you wanted.
   *bar_routine = \&DEF::routine;
}

print foo_routine(), "\n";   # ABC
print bar_routine(), "\n";   # DEF

use Module()
use Module qw()
防止调用模块的
import
。这里的模块没有定义任何默认导出,但我想明确说明我导入的内容。

根据描述,我假设您既不控制
ABC
也不控制
foo

因为这两个包中都没有
import
sub,所以它们的所有sub都生活在各自的包中。因此,如果加载
foo
ABC
也将被加载,并且代码将可供Perl使用。但是,
ABC
中的sub只能通过其完全限定名
ABC::routine
访问

事实上,这与LWP::UserAgent
require
s HTTP::Request时相同。现在,您可以在代码中使用HTTP::Request,而无需使用
use HTTP::Request
。您只将
use LWP::UserAgent
放在那里,因为它加载了另一个,所以它现在可用

当然,这些不出口东西,所以有点不同,但这基本上就是这里发生的事情


但是,如果不控制至少
foo.pm
就没有办法解决这个问题。
您不能覆盖
package
语句或声明程序的某个部分,其中
package
不起任何作用


更进一步说,您可能已经习惯了遗留代码,其中存在需要其他
.pl
文件的
.pl
文件,并且没有包。现在一个包成了一个问题,因为如果通常没有,也没有导出器,那么东西就会变得奇怪

我经常需要在包中包含带有大量全局变量的遗留代码,以将它们隐藏在我的
main
命名空间之外

package DoNotPutGlobalsInMyMain { require 'legacy.pl' };
但是,如果在
legacy.pl
中有另一个
包的显式定义,这将中断。因此,我的上述声明仍然有效。您需要控制该代码来修复它,或者知道哪个包真正包含要调用的sub


然后您可以
使用
自己要求
该软件包。只要
foo.pm
已经加载了它,就不会再加载它(因为Perl在
%INC
中记下它已经加载了它)。但是如果他们将它从
foo.pm
中删除,它仍然可用。您的维护程序员也了解您的依赖关系。

您在这里想要实现什么?这感觉像是XY问题。你能控制
ABC.pm
foo.pm
吗?是的,我不擅长问XY问题。。我喜欢他们帮助我理解东西是如何工作的,即使这不是一个很好的实践来真正使用答案。社区似乎不喜欢他们,所以我想我应该改掉这个习惯。社区已经在很多情况下因为追逐假设性的问题而被烧掉了,这些假设性的问题为非问题提供了糟糕的解决方案。问东西是如何工作的并没有错,但要清楚这就是你正在做的事情——作为一个关于perl的符号表是如何工作的问题,这很好。然而,乱搞符号表通常是一种疯狂的方式,对于一个特定的问题,通常有更好的解决方案。我同意@Sobrique。我也被标题所左右。在Perl中,确实有一种方法可以将某些内容作为其他内容导入,使用。这是我读了标题后首先回答的问题。然而,这个问题要求的完全是另外一件事我想OP还有别的意思。我也这么想,并发布了一个我已经删除的答案。但是如果你检查问题的最后一部分,你会看到包里面有包。这是另外一回事。
package foo;
use ABC qw( routine );

package bar;
use DEF qw( routine );

package main;
print foo::routine(), "\n";   # ABC
print bar::routine(), "\n";   # DEF
use ABC qw( );
use DEF qw( );
BEGIN {
   *foo_routine = \&ABC::routine;   # Could use foo::routine if you wanted.
   *bar_routine = \&DEF::routine;
}

print foo_routine(), "\n";   # ABC
print bar_routine(), "\n";   # DEF
package DoNotPutGlobalsInMyMain { require 'legacy.pl' };