Perl 动态查找加载模块的@EXPORT和@EXPORT\u OK

Perl 动态查找加载模块的@EXPORT和@EXPORT\u OK,perl,Perl,我正在编写一个脚本来清理隐式导入模块的代码。我想更改使用Foo的实例;使用Foo-qw-bar-baz 为了实现自动化,我想知道@Foo::EXPORT和@Foo::EXPORT\u OK的内容是什么。我试图在不使用PPI的情况下完成这项工作 因此,给定变量$module_name,如何访问该模块的@EXPORT和@EXPORT_OK?感谢Graham Knop指出了我需要的语法,以及PerlMonks的对话,其中包括: 感谢Graham Knop指出了我需要的语法,也感谢PerlMonks的对

我正在编写一个脚本来清理隐式导入模块的代码。我想更改使用Foo的实例;使用Foo-qw-bar-baz

为了实现自动化,我想知道@Foo::EXPORT和@Foo::EXPORT\u OK的内容是什么。我试图在不使用PPI的情况下完成这项工作


因此,给定变量$module_name,如何访问该模块的@EXPORT和@EXPORT_OK?

感谢Graham Knop指出了我需要的语法,以及PerlMonks的对话,其中包括:


感谢Graham Knop指出了我需要的语法,也感谢PerlMonks的对话,其中包括:


我认为您实际上是在问如何使用变量中的包名称访问包变量

通过一个软符号引用,您可以使用一个字符串。当Perl看到这不是一个引用时,它会使用它从字符串值计算出的包变量。strict不允许这样做,因此您必须关闭该部分检查:

my $class = 'Foo';
eval "require $class";  # or however you want to load it
my @exports = do {     
    no strict 'refs';
    @{$class . '::' . 'EXPORT'};
    };
基本上,你已经在自己的答案中完成了这项工作,并围绕着许多方便的东西。例如,运行时正在检查模块名的完整性,并将其转换为所需的文件名。这很好,但它掩盖了你的解决方案的实质


你提到PPI,但不是你不想使用它的原因。对于那些刚刚加入的人,您不一定能从静态分析中分辨出任何Perl变量中都包含什么。我将处理一些模块,这些模块根据导出列表的定义和其他条件动态构建导出列表。也就是说,@EXPORT和friends在单元编译结束之前是空的。这不是您应该做的事情,但这是可能的,而且静态上是不可检查的。

我想您真正想问的是,如何使用变量中的包名称访问包变量

通过一个软符号引用,您可以使用一个字符串。当Perl看到这不是一个引用时,它会使用它从字符串值计算出的包变量。strict不允许这样做,因此您必须关闭该部分检查:

my $class = 'Foo';
eval "require $class";  # or however you want to load it
my @exports = do {     
    no strict 'refs';
    @{$class . '::' . 'EXPORT'};
    };
基本上,你已经在自己的答案中完成了这项工作,并围绕着许多方便的东西。例如,运行时正在检查模块名的完整性,并将其转换为所需的文件名。这很好,但它掩盖了你的解决方案的实质


你提到PPI,但不是你不想使用它的原因。对于那些刚刚加入的人,您不一定能从静态分析中分辨出任何Perl变量中都包含什么。我将处理一些模块,这些模块根据导出列表的定义和其他条件动态构建导出列表。也就是说,@EXPORT和friends在单元编译结束之前是空的。这不是你应该做的事情,但这是可能的,而且静态上是不可检查的。

有一种不关闭狭窄的方法,即使用%:,但你这样做的方式是我推荐的。这样做更简单,并且没有必要隐藏这样一个事实,即我们确实在执行符号解引用you@ikegami如果没有导入,列表会变成空的。POSIX自己做事情。啊,是的。非常感谢。至少我现在也涵盖了这个用例:有一种方法可以在不关闭限制的情况下执行,即使用%:,但您执行此操作的方式是我推荐的方式。这样做更简单,并且没有必要隐藏这样一个事实,即我们确实在执行符号解引用you@ikegami如果没有导入,列表会变成空的。POSIX自己做事情。啊,是的。非常感谢。至少我现在也涵盖了这个用例:请注意,@EXPORT etc是特定于导出程序的,并非所有模块都使用它。即使他们这样做了,也不能保证它在包中是静态全局的。您应该首先检查它们,并将任何未定义它们的模块放在一边进行手动干预。模块的导入函数可以做任何它想做的事情。这就是为什么你必须在回答中使用POSIX->import。Exporter::Tiny也使用@EXPORT和@EXPORT__OK,但模块可以定义自定义子模块,这些子模块将覆盖它们的使用;例如,Types::Standard使用的Type::Library就是这样。我还发现这不适用于使用Sub::Exporter的任何东西。请注意@EXPORT等是特定于Exporter的,并非所有模块都使用它。即使他们这样做了,也不能保证它在包中是静态全局的。您应该首先检查它们,并将任何未定义它们的模块放在一边进行手动干预。模块的导入函数可以做任何它想做的事情。这就是为什么您必须在回答中执行POSIX->import。Exporter::Tiny也使用@EXPORT和@EXPORT\u OK,但模块ca
n定义将覆盖其使用的自定义Sub;例如,Types::Standard使用的Type::Library就是这样。我还发现这对使用Sub::Exporter的任何东西都不起作用。谢谢!你更清楚地表达了我措词笨拙的问题非常感谢。你更清楚地表达了我措词笨拙的问题