nashter
nashter

Reputation: 171

How to manipulate a hash-ref with Perl?

Take a look at this code. After hours of trial and error. I finally got a solution. But have no idea why it works, and to be quite honest, Perl is throwing me for a loop here.

use Data::Diff 'Diff';
use Data::Dumper;

my $out = Diff(\@comparr,\@grabarr);

my @uniq_a;

@temp = ();
my $x = @$out{uniq_a};
foreach my $y (@$x) {
    @temp = ();
    foreach my $z (@$y) {
        push(@temp, $z);
    }
    push(@uniq_a, [$temp[0], $temp[1], $temp[2], $temp[3]]);
}

Why is it that the only way I can access the elements of the $out array is to pass a hash key into a scalar which has been cast as an array using a for loop? my $x = @$out{uniq_a}; I'm totally confused. I'd really appreciate anyone who can explain what's going on here so I'll know for the future. Thanks in advance.

Upvotes: 1

Views: 392

Answers (3)

mob
mob

Reputation: 118605

$out is a hash reference, and you use the dereferencing operator ->{...} to access members of the hash that it refers to, like

$out->{uniq_a}

What you have stumbled on is Perl's hash slice notation, where you use the @ sigil in front of the name of a hash to conveniently extract a list of values from that hash. For example:

%foo = ( a => 123, b => 456, c => 789 );
$foo = { a => 123, b => 456, c => 789 };
print @foo{"b","c"};    # 456,789
print @$foo{"c","a"};   # 789,123

Using hash slice notation with a single element inside the braces, as you do, is not the typical usage and gives you the results you want by accident.

Upvotes: 4

Borodin
Borodin

Reputation: 126722

The Diff function returns a hash reference. You are accessing the element of this hash that has key uniq_a by extracting a one-element slice of the hash, instead of the correct $out->{uniq_a}. Your code should look like this

my $out = Diff(\@comparr, \@grabarr);

my @uniq_a;
my $uniq_a = $out->{uniq_a};
for my $list (@$uniq_a) {
  my @temp = @$list;
  push @uniq_a, [ @temp[0..3] ];
}

Upvotes: 2

scrappedcola
scrappedcola

Reputation: 10572

In the documentation for Data::Diff it states:

The value returned is always a hash reference and the hash will have one or more of the following hash keys: type, same, diff, diff_a, diff_b, uniq_a and uniq_b

So $out is a reference and you have to access the values through the mentioned keys.

Upvotes: 1

Related Questions