如何在perl中取消引用此哈希?

时间:2015-11-04 00:04:50

标签: perl hash reference subroutine

#!/usr/bin/perl
use Data::Dumper;

sub giveMeARef {
    my %hash = %{$_[0]};

    print "arg: ", Dumper($_[0]);
    print "deref: ", Dumper(%hash);
}

my %hash = ( "a" => (1,2,3), "b" => (3,4,5));

giveMeARef(\%hash);

这会产生以下输出:

arg: $VAR1 = {
          '2' => 3,
          '4' => 5,
          'a' => 1,
          'b' => 3
        };
deref: $VAR1 = 'b';
$VAR2 = 3;
$VAR3 = '2';
$VAR4 = 3;
$VAR5 = 'a';
$VAR6 = 1;
$VAR7 = '4';
$VAR8 = 5;

我尝试按照How do I dereference a Perl hash reference that's been passed to a subroutine?

中的示例进行操作

但是我相信因为我的哈希更复杂,所以它对我来说并不适合。我如何回到我传入的原始结构?

3 个答案:

答案 0 :(得分:6)

正如我在comment中提到的那样,您在创建%hash时会对列表进行展平。胖逗号(=>)是逗号的同义词,它使左边的裸字被解释为字符串,但在这种情况下它并不重要,因为你已经有了一个字符串左边。实际上,您的哈希分配实际上如下所示:

my %hash = ("a", 1, 2, 3, "b", 3, 4, 5);

看起来您正在尝试将数组分配给ab,但在Perl中,哈希值始终是标量,因此您需要使用对匿名数组的引用:

my %hash = (a => [1, 2, 3], b => [3, 4, 5]);

还值得注意的是,您的子例程正在为您传入的哈希引用制作一个浅表副本,这可能会产生意想不到/无法预料的后果。请考虑以下事项:

use Data::Dump;

sub giveMeARef {
    my %hash = %{$_[0]};
    pop(@{$hash{a}});
}

my %hash = (a => [1, 2, 3], b => [3, 4, 5]);

dd(\%hash);
giveMeARef(\%hash);
dd(\%hash);

哪个输出:

{ a => [1, 2, 3], b => [3, 4, 5] }
{ a => [1, 2], b => [3, 4, 5] }

答案 1 :(得分:3)

代码很好,但你的测试哈希不是你想象的那样。

你不能像那样构造一个哈希。那里的名单变得扁平了。你需要使用array-refs:

my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);

因为无论如何你都要引用那个哈希,你也可以从那里开始:

my $hash_ref = { a => [1,2,3], b => [3,4,5] };

答案 2 :(得分:1)

这里有两个问题:

  • Dumper用于打印哈希而不传递引用的方式,其中它解析为将所有元素打印为$ VAR1,$ VAR2等。

    自卸车(\%散列)

  • 初始化哈希的方式。由于该值是列表,因此应将其初始化为

    my%hash =(" a" => [1,2,3]," b" => [3,4,5]);

更正确的代码。

#!/usr/bin/perl
use Data::Dumper;

sub giveMeARef {
    my %hash = %{$_[0]};

    print "arg: ", Dumper($_[0]); #Dumper is passed a Ref.
    print "deref: ", Dumper(\%hash); # Dumper should be called with a hash ref.
}

my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);

giveMeARef(\%hash);