【问题标题】:How can I use a variable as a module name in Perl?如何在 Perl 中使用变量作为模块名称?
【发布时间】:2011-02-08 13:30:45
【问题描述】:

我知道在 Perl 中可以使用变量作为包变量的变量名。我想将变量的内容用作模块名称。例如:

package Foo;
our @names =("blah1", "blah2");
1;

在另一个文件中,我希望能够将标量的内容设置为“foo”,然后通过该标量访问Foo 中的名称数组。

my $packageName = "Foo";

基本上我想做一些类似的事情:

@{$packageName}::names; #This obviously doesn't work.

我知道我可以使用

my $names = eval '$'. $packageName . "::names" 

但前提是Foo::names 是一个标量。如果没有eval 语句,还有其他方法可以做到这一点吗?

【问题讨论】:

  • “访问 Foo”是什么意思?
  • 编辑了问题。我希望能够访问 foo 中的包变量“@names”

标签: perl module


【解决方案1】:

要获取包$package 中的包变量,您可以使用符号引用:

no strict 'refs';
my $package = 'Foo';

# grab @Foo::names
my @names = @{ $package . '::names' }

避免符号引用的更好方法是在Foo 中公开一个返回数组的方法。这是因为方法调用运算符 (->) 可以将字符串作为调用者。

package Foo;

our @names = ( ... );
sub get_names { 
    return @names;
}

package main;
use strict;

my $package = 'Foo';
my @names = $package->get_names;

【讨论】:

  • 我想我喜欢你描述的替代方法,只要我可以在 Foo 的基类中定义 get_names (我们将它称为 Bar 是原始的)这样我就可以在每个类中定义 @names它继承自 Bar。如果这有什么不同,我正在使用 Moose 对象。
  • @Paul,如果没有参数,则方法调用不需要括号。有些人喜欢总是包含一个空的() 以保持一致性,但如果可以的话,我通常会忽略它们。
  • 明白了。我个人更喜欢一致性。
  • 您也可以始终不使用括号。这是一致的。 :)
【解决方案2】:

Strict checking 阻止您使用变量(或文字字符串)作为名称的一部分,但这可以在本地禁用:

my @values;
{
    no strict 'refs';
    @values = @{"Mypackage"}::var;
}

【讨论】:

  • 基本上我正在做的是为 *.pm 查找一个目录,然后对于我发现的每个文件我都需要 $filename。加载这些模块后,我需要访问每个包中定义的 @names 变量。直到运行时我才知道包的名称,我所拥有的只是一个包含包名称的变量。
  • 我没有遇到从变量名加载包的问题 - 我已经把那部分记下来了。它访问这些包中的变量。这个答案肯定会在一小时前为我节省很多谷歌搜索:)
  • @mjn:哎呀抱歉,我现在正在编辑我的答案,以使真正的问题更加突出:)
  • 当我在 Perl v5.30.1 上尝试这个解决方案时,我得到一个错误:“Bareword found where operator expected at test15.pl line 4, near "}::var" (Missing operator before ::var?) syntax error at test15.pl line 4, near "}::var"
猜你喜欢
  • 2010-12-05
  • 2022-12-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多