perlhashsubroutine

Perl: can I skip the intermediate hash variable in this case?


At the moment, I use something like this:

my %tmpHash = routineReturningHash();
my $value = $tmpHash{'someKey'};

The only thing I need is $value, I do not need %tmpHash itself. So I am curious to know if there is a way to avoid declaring %tmpHash.

I tried

my $value = ${routineReturningHash()}{'someKey'};

but it doesn't work and outputs a strange error: "Can't use string ("1/256") as a HASH ref while "strict refs" in use".

Any ideas how it could be done?


Solution

  • Create a hashref out of the returned list, which you can then dereference

    my $value = { routineReturningHash() }->{somekey};
    

    In what you tried, the ${ ... } imposes the scalar context inside. From perlref (my emphasis)

    2.   Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type.

    In the scalar context the hash is evaluated to a string with fraction involving buckets; not a hashref.


    Update   I take it that there are design reasons for returning a hash as a flat list. If that isn't the case, then the clear solution is to just return a hashref from the sub.

    That also saves a data copy: When you return a hash the scalars (keys and values) need be copied, to provide a list to the caller; when you return a reference only that one scalar is returned.

    As for performance benefits ... if you can see a difference, you either have massive hashes which should be handled by reference anyway, or too many function calls what may need refactoring.

    To return by reference you can