perlhash

How do I use Perl keys() from a function return value?


I know about the Perl keys() function and would like to use it on a hash I have, but don't see any reason to set a variable to it. Let me explain in code two ways:

Normal:

my %hash = ReturnsHash();
foreach (keys(%hash)) {
    ...code...
}

The way I'd like:

foreach (keys(ReturnsHash())) {
    ...code...
}

With the second way I get this error message(Type of arg 1 to keys must be hash or array (not subroutine entry)) Is the second way possible? If so how?


Solution

  • Contrary to its name, ReturnsHash doesn't return a hash. It's impossible for a sub to return a hash. Subs can only return a list of scalars. If you do

    sub ReturnsHash {
       my %hash = ( a => 1, b => 2 );
       return %hash;
    }
    

    you're doing

    return 'a', 1, 'b', 2;
    

    Since you can't do

    keys('a', 1, 'b', 2)
    

    you can't do

    keys(ReturnsHash())
    

    Now, what you could do instead is return a reference to a hash

    sub ReturnsHashRef {
       my %hash = ( a => 1, b => 2 );
       return \%hash;
    }
    

    aka

    sub ReturnsHashRef {
       return { a => 1, b => 2 };
    }
    

    in which case you can do

    keys(%{ ReturnsHashRef() })
    

    Alternative

    You can do

    for my ( $k, $v ) ( a => 1, b => 2 ) {
       ...
    }
    

    so you can do

    for my ( $k, $v ) ( ReturnsHash() ) {
       ...
    }
    

    This requires Perl 5.36+, although it produces a (safe-to-ignore) experimental warning until Perl 5.40.