http://www.perlmonks.org?node_id=80399

entropy has asked for the wisdom of the Perl Monks concerning the following question: (references)

I can take a slice of an array ref, but not of a hash ref:
my $arr =[1,'a',2,'b']; my $hash={1,'a',2,'b'}; print join ':',(@$arr )[1,2]; print join ':',(@$hash){1,2};
The first print statement works, the second is a syntax error. I also have this problem when taking a slice of an anonymous hash:
print join ':',(1,'a',2,'b')[1,2]; print join ':',(1,'a',2,'b'){1,2};
Again, the first statement works, but the second is a syntax error.

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How do I take a slice of a hash reference?
by japhy (Canon) on May 15, 2001 at 03:36 UTC
    Here's how:
    @slice = @{$array_ref}[ @idx ]; @slice = @{$hash_ref}{ @keys };
    And there's no easy way to "pretend" a list is a hash. You need to use a hash reference explicitly:
    $scalar = {1, 'a', 2, 'b'}->{$key}; @slice = @{ { 1, 'a', 2, 'b' } }{ @keys };
Re: How do I take a slice of a hash reference?
by dkubb (Deacon) on May 15, 2001 at 09:18 UTC

    Another way to get a slice from a hash reference is:

    my $hashref = { a => 1, b => 2, c => 3, d => 4, }; #Pull out elements a and d from the hashref my @slice = @$hashref{ qw(a d) };

    Originally posted as a Categorized Answer.

Re: How do I take a slice of a hash reference?
by tianping (Initiate) on Jun 02, 2011 at 08:40 UTC
    japhy has answered the question, but it's also worth pointing out the solution to the syntax error in your original code. The parentheses alter the priority; so just remove them:
    print join ':', @$hash{1,2};
    More generally, put curly braces around the hash ref expression:
    print join ':', @{$hash}{1,2};
Re: How do I take a slice of a hash reference?
by tachyon (Chancellor) on May 21, 2001 at 09:44 UTC
    All that is wrong with your code is the parenths. Join takes a list ie: join '', (list); To give list context to your hash slice all we need to do is move the parenths as shown, this runs fine.

    Note that we do not need parenths for the array at all.

    my $arr = [1,'a',2,'b']; my $hash = {1,'a',2,'b'}; print join ':', @$arr[1,2]; print join ':',(@$hash{1,2});

    tachyon

      Wrong button, especially with a missing </code> Scorn pours forth like a raging torrent....

      All that is wrong with your code is the parenths. Join takes a list ie: join '', (list); To give list context to your hash slice all we need to do is move the parenths as shown, this runs fine.

      my $arr = 1,'a',2,'b'; my $hash= {1,'a',2,'b'}; print join ':', @$arr1,2; print join ':',(@$hash{1,2});

      Note that we do not need parenths for the array at all.

      tachyon