我已经创建了一个子函数,它返回对包含7-8个变量的属性散列的引用。每当我想访问一个元素时,我要么重新定义它为my $n_players = $ref_attr->{'n_players'},要么直接调用它为$ref_attr->{'n_players'}。我更喜欢使用所有重新定义的变量(第一种情况),然而这需要7-8行初始化,并使我的代码变得混乱。
有没有一个模块(我似乎找不到)或者一个很好的方法来导出散列键作为变量?
发布于 2011-01-30 07:33:44
可以使用hash slices来减少从散列中获取多个条目所涉及的重复。您可以在初始化副本时使用它,例如(假设您也有一个n_teams条目):
my ($n_players, $n_teams) = @$ref_attr{qw( n_players n_teams )};正如Eric Strom建议的那样,您还可以使用缩进来帮助确保您拥有正确顺序的密钥:
my ($n_players, $n_teams) = @$ref_attr{
qw( n_players n_teams)
};正如其他人所说,可以操作符号表来创建对应于每个键的变量,但这不是一个好主意。
发布于 2011-01-30 07:39:03
您可以使用引用和散列片轻松完成此操作:
sub takes_hashref {
my $hashref = shift;
my ($one, $two, $three, $four, $five) = \@$hashref{
qw(one two three four five)
};
print "one: $$one, two: $$two, three: $$three, ",
"four: $$four, five: $$five\n";
$_++ for $$one, $$three, $$five;
}
my %hash = qw(one 1 two 2 three 3 four 4 five 5);
takes_hashref \%hash; # one: 1, two: 2, three: 3, four: 4, five: 5
takes_hashref \%hash; # one: 2, two: 2, three: 4, four: 4, five: 6
takes_hashref \%hash; # one: 3, two: 2, three: 5, four: 4, five: 7@$hashref{qw(x y z)}是一个哈希片,它返回值的列表。前置\获取对每个值的引用并返回引用列表。然后将其赋给您的词法变量。当您使用每个变量时,将sigil加倍以取消对其的引用:$$var。由于这些变量包含对散列字段的引用,因此可以为它们赋值:$$var = 'new val',赋值将更改原始散列。如果您不关心变量的更改会传播回散列,那么可以省略散列切片上的\,以及所有变量上的双符号。
如果您只想创建一个较短的别名来使用,您可以在您的sub中本地化%_:
sub takes_hashref2 {
my $hashref = shift;
local *_ = \%$hashref;
print "one: $_{one}, two: $_{two}, three: $_{three}, ",
"four: $_{four}, five: $_{five}\n";
$_++ for @_{qw(one three five)};
}
my %hash = qw(one 1 two 2 three 3 four 4 five 5);
takes_hashref2 \%hash; # one: 1, two: 2, three: 3, four: 4, five: 5
takes_hashref2 \%hash; # one: 2, two: 2, three: 4, four: 4, five: 6
takes_hashref2 \%hash; # one: 3, two: 2, three: 5, four: 4, five: 7行local *_ = \%$hashref将%_作为$hashref中的散列的别名。\%部分不是必需的,但如果$hashref中的值不是哈希值,则会抛出错误。这只是一种更简短的写作方式:
die 'not a hash' unless ref $hashref eq 'HASH';
local *_ = $hashref;您可以在一行中将其写为:
local *_ = \%{shift @_};发布于 2011-01-30 06:55:46
要么显式地复制它们(你的第一个选项),要么直接使用散列(你的第二个选项)。从长远来看,这一点要清晰得多。
..。
但如果您真的想这样做,散列%::就是您当前的包变量散列(是的,perl内部)。你可以玩它。
perl -e'print %::';https://stackoverflow.com/questions/4839968
复制相似问题