我正在向子例程发送一个哈希,并使用my($arg_ref) = @_;
但究竟是什么%$arg_ref
? %$
取消引用哈希值吗?
答案 0 :(得分:19)
$arg_ref
是一个标量,因为它使用了$
sigil。据推测,它拥有哈希引用。所以是的,%$arg_ref
干扰哈希引用。另一种写作方式是%{$arg_ref}
。这使代码的意图更加清晰,但更详细。
引用perldata(1)
:
Scalar values are always named with '$', even when referring
to a scalar that is part of an array or a hash. The '$'
symbol works semantically like the English word "the" in
that it indicates a single value is expected.
$days # the simple scalar value "days"
$days[28] # the 29th element of array @days
$days{'Feb'} # the 'Feb' value from hash %days
$#days # the last index of array @days
所以你的例子是:
%$arg_ref # hash dereferenced from the value "arg_ref"
my($arg_ref) = @_;
抓取函数参数堆栈中的第一项,并将其放在名为$arg_ref
的局部变量中。调用者负责传递哈希引用。一种更规范的写作方式是:
my $arg_ref = shift;
要创建哈希引用,您可以从哈希开始:
some_sub(\%hash);
或者您可以使用匿名哈希引用创建它:
some_sub({pi => 3.14, C => 4}); # Pi is a gross approximation.
答案 1 :(得分:7)
您可以使用
抓取单个项目,而不是像这样取消引用整个哈希值$arg_ref->{key}
答案 2 :(得分:4)
Perl中对引用(创建它们和使用它们)的简要介绍是perldoc perfeftut
。您也可以read it online(或以PDF格式获取)。 (它更多地讨论了复杂数据结构中的引用,而不是传入和传出子例程,但语法是相同的。)
答案 3 :(得分:2)
my %hash = ( fred => 'wilma',
barney => 'betty');
my $hashref = \%hash;
my $freds_wife = $hashref->{fred};
my %hash_copy = %$hash # or %{$hash} as noted above.
Soo,语法灵活性的重点是什么?我们试试这个:
my %flintstones = ( fred => { wife => 'wilma',
kids => ['pebbles'],
pets => ['dino'],
}
barney => { # etc ... }
);
实际上对于像这样的深度数据结构,从ref:
开始通常更方便my $flintstones = { fred => { wife => 'Wilma',
kids => ['Pebbles'],
pets => ['Dino'],
},
};
好的,弗雷德得到了一只新宠物,“迅猛龙”
push @{$flintstones->{fred}->{pets}}, 'Velociraptor';
弗雷德有多少只宠物?
标量@ {flintstones-> {fred} - > {pets}}
让我们喂他们......
for my $pet ( @ {flintstones->{fred}->{pets} } ) {
feed($pet)
}
等等。卷曲的汤一开始看起来有点令人生畏,但最终处理它们变得非常容易,只要你处理它们的方式一致。
答案 4 :(得分:1)
因为有点清楚这个构造用于提供哈希引用作为sub的命名参数列表,所以也应该注意这个
sub foo {
my ($arg_ref) = @_;
# do something with $arg_ref->{keys}
}
与仅解包@_ 相比,可能过度杀伤
sub bar {
my ($a, $b, $c) = @_;
return $c / ( $a * $b );
}
取决于参数列表的复杂程度。