wirrwarr has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,
I have a function returning a hash, like
sub func { return ('a' => 'ah', 'b' => 'be') };
now I'd like to apply the internal perl function keys to this function. I tried
keys func(); keys ( func() ); keys ( &func() );
all of which give the following error:
Type of arg 1 to keys must be hash (not subroutine entry)
It works if I use a temporary variable though:
my %hash = func(); keys %hash;
Now is there a way I can use the function directly? Or doesn't Perl's syntax allow this? perldoc perlfunc gives following description:
Returns a list consisting of all the keys of the named hash. ...
which seems to imply I have to use a variable.

Thanks for any insights on this!

Replies are listed 'Best First'.
Re: Apply function "keys" directly to function returning hash
by benn (Vicar) on Aug 25, 2003 at 16:48 UTC
    The problem is that you're *not* returning a hash - you're returning a list, which my %hash = func() turns into a hash for you.

    One way round this would be to return a hashref instead - something like this...

    sub func { return {'a' => 'ah', 'b' => 'be'} }; print keys %{func()}; # a b
    Hope this helps,
    Ben.
Re: Apply function "keys" directly to function returning hash
by herveus (Prior) on Aug 25, 2003 at 16:50 UTC
    Howdy!

    I got somewhere with keys %{{func()}}

    func() returns a list\

    {func()} constructs an anonymous hash from that list

    %{} around that tries to dereference what is inside it as a hash reference (ending up with the hash keys wants)

    keys # take keys of following HASH %{ # dereference HASHREF { # construct HASHREF from list func() # returns list } }

    yours,
    Michael

      Oh yes, that's the solution.
      I already tried %{\(func())}, but I always forget that \() is not the same as {}. :(
      Thanks a lot!
Re: Apply function "keys" directly to function returning hash
by sgifford (Prior) on Aug 25, 2003 at 19:19 UTC
    Essentially you want to keep all of the even-numbered array elements, and discard all of the odd ones. Something like this will do that:
    my $i = 1; print join(" ",grep { $i++ % 2 } l()),"\n";
      Hmm. Well, yes, this *does* get me the keys of the hash, but my intent was rather more general: I wanted to be able to call a perl internal function which takes a hash directly with a function call as a parameter, i.e. "somefunc func()".
      But thanks anyways!.

      daniel.
        It's not an internal function, but it does work exactly as you describe:
        #!/usr/bin/perl -sw use strict; sub somefunc(@) { my $i = 1; grep { $i++ % 2 } @_; } sub func { return ( 1 => "one", 2 => "two", 3 => "three", ); } print join(" ",somefunc func());