如何在Perl中使用符号引用?
在Perl中,如果一个变量包含另一个变量的名称,如何使用第一个变量访问另一个变量 例如,让如何在Perl中使用符号引用?,perl,variables,Perl,Variables,在Perl中,如果一个变量包含另一个变量的名称,如何使用第一个变量访问另一个变量 例如,让 $name = "bob"; @bob = ("jerk", "perlfan"); 我应该如何使用$name来了解bob是什么样的人? 虽然我不太确定,但我模糊的记忆告诉我这可能与typeglob有关。这是一种非常糟糕的做法。如果你曾经需要这样做,这意味着你应该重构你的代码。也许使用命名键的哈希会更好: my %data = ( 'bob' => [ 'jerk', 'perlfan'
$name = "bob";
@bob = ("jerk", "perlfan");
我应该如何使用$name来了解bob是什么样的人?
虽然我不太确定,但我模糊的记忆告诉我这可能与typeglob有关。这是一种非常糟糕的做法。如果你曾经需要这样做,这意味着你应该重构你的代码。也许使用命名键的哈希会更好:
my %data = (
'bob' => [ 'jerk', 'perlfan' ],
);
my $name = 'bob';
print $data{ $name }->[0], "\n";
print $data{ $name }->[1], "\n";
my $stringified = join ' and ', @{ $data{ $name } };
print $stringified, "\n";
你真的不应该这么做,看看depesz的答案,但是
{
no strict 'refs';
print join(q{, }, @$name);
}
是的,您可以使用字符串标量作为变量引用,它会按名称查找变量
您也可以使用typeglobs执行此操作,有关简单方法,请参见符号模块。几点:
- 您不是在谈论typeglobs,而是在谈论符号引用
- 不要使用符号引用——它们会导致难以追踪的bug
- 几乎在任何情况下,符号引用似乎都是一个好主意,使用基于散列的数据结构是最好的方法
- 考虑使用Hash::Util在您不想更改哈希时锁定它们
- 符号引用对词汇变量不起作用
- Typeglobs对词汇变量不起作用
- 使用词汇变量
- 不要使用符号引用
use strict;
use warnings;
use Hash::Util qw( lock_hash unlock_hash );
my %data;
lock_hash( %data );
#Altering %data is a fatal exception.
unlock_hash( %data );
%data = (
'bob' => [ 'jerk', 'genius' ],
);
lock_hash( %data );
for my $name (qw/ bob margaret /) {
my $info = $data{$name}; # Fatal error when accessing data for margaret.
print "$name is a\n";
print map "\t$_\n", @$info;
}
抛开所有警告不谈,如果需要使用符号引用(但不需要),则使用符号引用的语法是:
注意,数组@bob
是用our
声明的。符号引用仅适用于符号表中的值。换句话说,词汇变量不适用于符号引用
为了防止我没有充分强调这一点,不要使用符号引用请参见:
初学者通常认为他们想要一个包含变量名的变量
简短的回答:不要。详细解答:阅读常见问题解答条目(也可在您的计算机上找到)。较长的答案:阅读MJD的(,)。通常当您认为需要使用符号引用时,使用哈希(关联数组)会更好 结果: jerk perlfan mary had a little lamb susan not found 返回: jerk perlfan # mary is not an array, it's a scalar mary had a little lamb susan not found 杰克帕尔凡 #mary不是数组,而是标量 玛丽有一只小羊羔 苏珊没有找到
您应该注意到,很难安全地使用符号引用,这就是为什么不应该使用它们的原因
当然,除非你是做一些高级工作的专家。符号引用是值得避免的,但是如果你真的想使用它们,它们的使用语法与常规引用相同:请参阅。+1以获得技术上正确的答案,并同意你永远不应该这样做。完全正确。在第二颗子弹之后,你很容易就停下来了。我相应地编辑了问题的标题。+1从技术上正确、令人惊讶地全面地解释了如何做以及为什么不做。+1避免不良做法要比找到使不良做法发生的方法好得多。这就是象征性引用所做的:邪恶在于,通过使用象征性引用,一种是将程序的符号表视为自己的私有哈希,当然,它不是。所以,使用散列。不要使用符号引用。(我认为这一点强调得不够)。
use strict;
use warnings;
my %user = (
'bob' => [qw' jerk perlfan '],
'mary' => 'had a little lamb',
);
{
for my $name (qw'bob mary susan'){
if( exists $user{$name} ){
if( ref($user{$name}) eq 'ARRAY' ){
print join( ' ', @{$user{$name}} ), "\n";
}else{
print $name, ' ', $user{$name}, "\n";
}
}else{
print "$name not found\n";
}
}
}
jerk perlfan
mary had a little lamb
susan not found
use strict;
use warnings;
# can't use my
our @bob = ("jerk", "perlfan");
our $mary = 'had a little lamb';
{
for my $name (qw'bob mary susan'){
if( exists $::{$name} ){
my $ref = $::{$name};
if( *{$ref}{ARRAY} ){
print join(' ',@$ref), "\n";
}elsif( *{$ref}{SCALAR} ){
print "# $name is not an array, it's a scalar\n";
print $name, ' ', $$ref, "\n";
}
}else{
print "$name not found\n"
}
}
}
jerk perlfan
# mary is not an array, it's a scalar
mary had a little lamb
susan not found