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

Dear Monks,
Can I do the following. I have a function which input is an array ref. I have a hash %hash and do not want to convert its keys to an array separately. Can I do something like:
my_function( [keys (%hash)] ) ...... sub my_function { $arr_ref = shift; ...... }

Replies are listed 'Best First'.
Re: passing array ref without variable
by kennethk (Abbot) on May 03, 2010 at 14:34 UTC
    Your syntax would probably work, depending on your expectations. Fortune favors the bold - make a mock-up script and see what happens!

    The syntax will pass an anonymous array whose contents are the keys of your hash. By using keys, however, you are breaking the link with the actual element itself (lvalue). This means that the function cannot change the values themselves, i.e. if this function normally removes all 'x's from the elements of the array, the hash keys will remain unchanged.

Re: passing array ref without variable
by AnomalousMonk (Archbishop) on May 03, 2010 at 15:00 UTC

    Yes, just try it – and see what happens with Data::Dumper or any of its ilk. (Also nice to use strictures and warnings!)

    >perl -wMstrict -le "use Data::Dumper; my %hash = qw(a 1 b 2 c 3 d 4); my_function([keys %hash]); sub my_function { my $arr_ref = shift; print Dumper $arr_ref; } " $VAR1 = [ 'c', 'a', 'b', 'd' ];
      Can I pass somehow an array ref of values without separately forming an array? Maybe using foreach...
        Why would you want to? Inline anonymous array construction is a trivial number of characters and is robust. This sounds like an XY Problem.
        I suppose what you really want/need is to pass the hash as reference, like this you don't need to pass the values and the keys separately.

         call(\%hash)

        If you explicitly want to pass the reference of a copy do this

         call( { %hash } )

        the { ... } returns a ref of an anonymous hash of the list expanded from %hash, i.e. the ref of a hashcopy!

        Cheers Rolf

        Why would you want to? And how could you? It sounds like you (vit) are asking "Can I take a reference to an array that does not exist?".

Re: passing array ref without variable
by Anonymous Monk on May 03, 2010 at 14:22 UTC
    Yes, just try it
Re: passing array ref without variable
by ambrus (Abbot) on May 04, 2010 at 13:11 UTC

    Yes, that does work. What does not work so easily is when you want to pass the values of a hash to the function in such a way that it can write them. Eg. this works, the function can change the value in the hash:

    my %d = ("foo", "bar"); sub fs { $_[0] = "quux"; } fs(values %d); prin +t join(" ", %d), $/; # OUTPUT: foo quux

    But this does not work:

    my %d = ("foo", "bar"); sub fi { ${$_[0]}[0] = "quux"; } fi([values %d +]); print join(" ", %d), $/; # OUTPUT: foo bar

    Instead you could do

    my %d = ("foo", "bar"); sub fi { ${$_[0]}[0] = "quux"; } sub capture { + \@_ } fi(capture(values %d)); print join(" ", %d), $/; # OUTPUT: foo quux

    But that's probably all irrelevant to your question.