【问题标题】:How to use a package with a variable name如何使用带有变量名的包
【发布时间】:2014-01-29 03:27:58
【问题描述】:

我的最终目标是使用参数作为包。我无法得到一个简单的例子来工作。有没有办法将use$variable 作为我的包裹?

我的模块.pm

package MyModule;
use strict;
use warnings;
use parent 'Exporter'; # imports and subclasses Exporter

our $test="hello world\n";
our @EXPORT = qw($test);

程序.pl

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

my $x = 'MyModule.pm';
eval "require $x";
MyModule->import;
print "$test\n";

错误

Global symbol "$test" requires explicit package name at ./program.pl line 8.
Execution of ./program.pl aborted due to compilation errors.

【问题讨论】:

  • 我敢打赌,您的 require 声明中有错误。在eval 调用之后检查$@ 的值。
  • 对 require 的规范调用通常是 require MyModule 或有时是 require 'MyModule.pm' 但不是 require MyModule.pm
  • 不确定这是否是您的错误的具体原因,但请记住,您需要单独以 1; 结束您的包文件。
  • 我很想知道让你问这个问题的根本问题;很可能有更好的方法来解决它。
  • 是的,有一个更简单的方法;跳过所有导入/模块的东西,只做my $file = 'ArrayA'; my $test = do "$file.data";,其中 ArrayA.data 只包含数组数据(例如[[1,2,3],[4,5,6]]

标签: perl variables module package


【解决方案1】:

require 有两种语法;一个需要一个不带引号的包名(例如require Foo::Bar;),另一个需要一个产生文件名的表达式(例如require "Foo/Bar.pm";)。请注意,后者仍然搜索库目录,并在组件之间使用/,即使在使用其他路径分隔符的系统上也是如此。

你的:

my $x = 'MyModule.pm';
eval "require $x";

尝试评估代码require MyModule.pm 会混淆这两种形式并给出错误Bareword "pm" not allowed while "strict subs" in use(被评估捕获并放在$@ 中)。

所以要么只做my $x = 'MyModule';(并检查 eval 是否发现错误,以确保稳健性),要么只做:

my $x = 'MyModule.pm';
require $x;

(或eval { require $x },如果您希望捕获错误)。

这仍然会在$test 上留下您的严格错误,因为$test 直到运行时才会导出,并且严格检查是在编译时;要解决这个问题,您需要能够在编译时执行您的要求:

#!/usr/bin/perl
use 5.014;
use warnings;

BEGIN {
    my $x = 'MyModule';
    my $filename = "$x.pm" =~ s!::!/!gr;
    require $filename;
    $x->import;
}
say $test;

【讨论】:

  • 我在 BEGIN 块内将其简化为 require 'MyModule.pm'MyModule->import; 并得到错误:can't locate parent.pm... at MyModule.pm line 5 是正确的 use exporter
  • 那么,您有一个旧的 perl 并没有与 parent 一起提供。您可以从 CPAN 获取父级。但是假设你没有一个非常古老的 perl,你可以只做 use Exporter 'import'; 而不是继承 Exporter。
  • 谢谢!我将我的 Perl 路径更改为更新版本,我们现在开始营业了。我可以将参数传递给BEGIN 块吗?您能否编辑代码示例以使用第一个参数$_[0]
  • @Stuart,我没这么说。您可以在 BEGIN 块中使用传递给脚本的参数。 (您曾问过如何将参数传递给 BEGIN 块。)
  • 是的,参数在 BEGIN 块中作为 @ARGV 可用,环境作为 %ENV
猜你喜欢
  • 1970-01-01
  • 2011-11-27
  • 2013-04-27
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2011-12-08
  • 2011-12-15
相关资源
最近更新 更多