Home > Mobile >  In Perl when you return a hash from a sub what is the "quick way" to acess a specific valu
In Perl when you return a hash from a sub what is the "quick way" to acess a specific valu

Time:10-17

In Perl, it seams, there is no "simple" way to address a hash directly when it is returned from a sub or am I missing something?

I would like something like this.

print ( (hash()){One} ); # Not a thing!

You can do that whit an array since the values returned constitute a list.

print ( (arr())[0] );

But for a hash that does not cut it. I have come up with some ways to sort of get this to work.

print ( ${{hash()}}{One} );
print ( 0 {hash()}->{One} );

But they seem kinda lame. I mean this is hard to read and reference shenanigans seams out of place for such a simple thing.

Here is more code for context.

use strict;
use warnings;

### ARRAY
sub arr {
    my @arr = (
        1,
        2,
        3,  
    );
    return @arr;
}

print ( (arr())[0] ); #Output is 1; 

### HASH
sub hash {
    my %hash = (
        One   => 1,
        Two   => 2,
        Three => 3,
    ); 
    return %hash;
}

my %hash = hash();


#print ( (hash()){One} );       # Does not work
print ( $hash{One}  );          # Output is 1
print ( (hash())[0] );          # Output will be One, Two or Three
print ( (hash())[1] );          # Output will be 1, 2, 3
print ( ${{hash()}}{One} );     # Output is 1
print ( 0 {hash()}->{One} );    # Output is 1;
# 0  because Perl gives syntax error otherwise. Not sure why (Scalar context?) but one mystery at a time. 

CodePudding user response:

Subroutines do not return hashes, but a list of values. This list can be converted to a hash.

Given a sub that returns an even-sized list, I would use the following expression to access a hash entry:

 {hash()}->{One}

The leading is sometimes necessary to disambiguate a hash reference literal {...} from a statement-level block {...}1. The unary plus is a no-op and just forces expression context, whereas 0 would convert the value to a number.

1. Though in this particular instance the ambiguity is due to the print(FILEHANDLE LIST) syntax, where the filehandle can be enclosed in curly braces.

If you have control over the function attempting to return a hash, it could be worth considering to return a hash reference instead. Your example would then look like:

sub hashref {
    # alternatively: "return { One => 1, ... };"
    my %hash = (
        One   => 1,
        Two   => 2,
        Three => 3,
    ); 
    return \%hash;
    #      ^-- create a reference to the hash
}

my %hash = hashref()->%*;  # or "%{hashref()}". Note that this makes a copy

print( hashref()->{One} );  # can directly access keys
  • Related