如何在 Perl 中使用变量作为变量名?

问题描述 投票:0回答:4

我需要在perl中实现以下目标

printmsg(@val1, $msg1) if @val1;
printmsg(@val2, $msg2) if @val2;
printmsg(@val3, $msg3) if @val3;
printmsg(@val4, $msg4) if @val4;
printmsg(@val5, $msg5) if @val5;
printmsg(@val6, $msg6) if @val6;

所以我写了以下片段

for(my $i=1; $i < 6; $i++ ) {
    printmsg(@val$i, $msg$i) if @val$i;
}

它不起作用并出现错误。

perl symbolic-references
4个回答
37
投票

每当您发现自己在变量名称后缀了整数索引时,请意识到您应该使用数组来代替:

my @msgs = ('msg1', 'msg2', ..., 'msg6');
my @vals = ( [ @val1 ], [ @val2 ], ..., [ @val6 ] );

另请参阅常见问题解答 如何使用变量作为变量名称?

正如常见问题解答的答案所述,如果变量不是由整数索引,则可以使用哈希表:

通过使用符号引用,您只需使用包的符号表哈希(如

%main::
)而不是用户定义的哈希。解决方案是使用您自己的哈希或真实的引用。

$USER_VARS{"fred"} = 23;
my $varname = "fred";
$USER_VARS{$varname}++;  # not $$varname++

您应该每年至少阅读一次完整的常见问题解答列表。

更新:我故意在答案中省略了符号引用,因为它们是不必要的,并且在您的问题中可能非常有害。有关更多信息,请参阅 mjd为什么‘使用变量作为变量名’很愚蠢?第 2 部分第 3 部分


5
投票

您不能像这样将变量串在一起并获得结果变量。您可以计算

$msg + i
的表达式,但如果将 msg 设为数组并仅索引:
$msg[$i]
,可能会更好。


3
投票

如果我理解,你需要“评估”!

for(my $i=1; $i < 6; $i++ ) {
  eval 'printmsg(@val'. $i . ', $msg' . $i .') if @val' . $i;
}

但请记住!所有变量(@val1,@val2,...,@valN)必须存在!由于您没有提供太多代码,我无法推断有关此问题的更多信息。也许你可以提供更多代码吧?


0
投票

尝试用 eval 进行插值是一个有趣的解决方案,而且看起来它会起作用。 我从未考虑过尝试使用 eval 来组合变量名称。 但原因是数组效果更好,并且可能是技术上正确的解决方案。

不要尝试在 eval 中连接“$var”和“$i”以形成“$var1”,只需使用数组并访问 $var[$i]。 代码看起来像这样。

#!/usr/bin/perl -w
    
my @arrayOfReferences;

push @arrayOfReferences, [qw(this is array 1)];
push @arrayOfReferences, [qw(this is array 2)];
push @arrayOfReferences, [qw(this is array 3)];
push @arrayOfReferences, [qw(this is array 4)];
push @arrayOfReferences, [qw(this is array 5)];
push @arrayOfReferences, [qw(this is array 6)];

my @arrayOfMessages = qw(Message1 Message2 Message3 Message4 Message5 Message6);

for (my $i=0; $i < @arrayOfMessages; $i++){
  &printmsg($arrayOfReferences[$i],$arrayOfMessages[$i]);
}

sub printmsg{
  ($arrayRef, $message) = @_;
  print "Array Value: " . join(" ",@$arrayRef) . "\n"; #dereference pointer here
  print "Message String: $message\n\n";
}

输出看起来像这样

perl evalVariableInterpolation.pl
Array Value: this is array 1
Message String: Message1

Array Value: this is array 2
Message String: Message2

Array Value: this is array 3
Message String: Message3

Array Value: this is array 4
Message String: Message4

Array Value: this is array 5
Message String: Message5

Array Value: this is array 6
Message String: Message6
© www.soinside.com 2019 - 2024. All rights reserved.