%$ var是否取消引用Perl哈希?

时间:2009-02-18 20:54:20

标签: perl reference

我正在向子例程发送一个哈希,并使用my($arg_ref) = @_;

获取它

但究竟是什么%$arg_ref%$取消引用哈希值吗?

5 个答案:

答案 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 );
}

取决于参数列表的复杂程度。