Every time I take a slice of a hashref I have to reteach myself the syntax. I usually do that using the debugger. I often spend way too long with the task, taking wrong turns and confusing myself to no end.
Today I noticed that this works in the debugger:
DB<1> $r = {this => 'that', these => '17'} DB<2> @f = qw(this these) DB<3> x {%$r}{@f} 0 'this' 1 'these'
The debugger's x command outputs this construction just fine. Yet when I try to assign the results of this expression to an array, either in the debugger or in a program, I get an error:
DB<4> @i = {%$r}{@f} syntax error at (eval 32)[/usr/local/perl/5.10.0/lib/5.10.0/perl5db.pl:638] line 2, near "}{"
The correct syntax is:
@i = @{$r}{@f};
Hopefully I won't have to figure it out from scratch again the next time. :) But why does the invalid construction above work for the debugger's x command?
DB<13> @r = qw(this that these 17)
DB<14> x {%$r}{@r}
0 'this'
1 'that'
2 'these'
3 17
DB<15> x {@r}
0 'this'
1 'that'
2 'these'
3 17
DB<16> x @r
0 'this'
1 'that'
2 'these'
3 17
Re:array
jdavidb on 2008-07-29T17:32:53
You're right. I'm getting keys, not values. I should pay more attention to detail.
:) So what about the debugger is making it ignore the first part in braces, I wonder.
This might not help, but I remember hash slices as follows. First really it's just a hash:
my $hashref = {a => 1, b => 2, c=> 3};
# it's just a hash:
%$hashref;
Second we do our lookup:
my @of_interest = qw(a c);
%$hashref{@of_interest};
Slices return lists, so we need an @ sign instead of the %:
@$hashref{@of_interest};
Which gives us:
use strict;
use warnings;
my $hashref = {a => 1, b => 2, c=> 3};
my @of_interest = qw(a c);
print "@$hashref{@of_interest}\n";
You can go the other direction too. If it were just a regular hash (no reference) you'd write:
print "@hash{@of_interest}\n";
Because there's that reference there, you need to add in that $. But this way seems to confuse people more.
The expression you're supplying to the debugger is being parsed as a block:
tony@zeus:~$ perl -MO=Deparse -e '{%$r}{@f}'
{
%$r;
}
{
@f;
}
-e syntax OK
eval()ling the same expression gives the result you saw in the debugger:
tony@zeus:~$ perl -e '$r = { this => "that", these => 17 }; @f = qw(this these); @foo = eval q"{%$r}{@f}"; use Data::Dumper; print Dumper \@foo'
$VAR1 = [
'this',
'these'
];
Re:Parsed as blocks
jdavidb on 2008-07-30T12:45:36
Ah! Thank you for the explanation!