in reply to How it works?

Assume your hash has 15 keys. @_ is a list of all the keys. As an EXPR for rand, @_ is evaluated in scalar context, which results in the number of items in the array (15). rand @_ is like rand 15, which returns an integer between 0 and 14. Say it returns 6. Then, the 7th key ($_[6]) is returned by the sub.

UPDATE: I agree with the reply below that rand does not return an integer.

Replies are listed 'Best First'.
Re^2: How it works?
by kcott (Archbishop) on Jan 21, 2016 at 05:05 UTC
    "rand @_ is like rand 15, which returns an integer between 0 and 14."

    Actually, that's incorrect (with respect to rand returning an integer). The first sentence of the rand documentation reads:

    "Returns a random fractional number greater than or equal to 0 and less than the value of EXPR."

    As an example (which I'll continue to use below):

    $ perl -le '$x = rand 2; print $x' 0.0874574767967786

    I believe, although I can't find any documentation to back it up, that Perl knows the index must be an integer and applies a behind-the-scenes int (or equivalent) to the index. I can use the above rand result directly without getting a warning:

    $ perl -wle '@y = qw{a b c}; print $y[0.0874574767967786]' a

    Even B::Deparse only reports 0 as the index:

    $ perl -MO=Deparse -e '@y = qw{a b c}; print $y[0.0874574767967786]' @y = ('a', 'b', 'c'); print $y[0]; -e syntax OK

    I'd be interested if anyone has more information about this (including, but not limited to, if this behaviour is documented).

    — Ken

      Implicit int-ing also works at run-time:

      c:\@Work\Perl\monks>perl -wMstrict -le "my @ra = qw(e h l o); my ($i, $j, $k, $l) = (0.99876, 1.00123, 2.499999, 3.5); print $ra[$j], $ra[$i], $ra[$k], $ra[$k], $ra[$l]; " hello c:\@Work\Perl\monks>perl -wMstrict -MO=Deparse,-p -le "my @ra = qw(e h l o); my ($i, $j, $k, $l) = (0.99876, 1.00123, 2.499999, 3.5); print $ra[$j], $ra[$i], $ra[$k], $ra[$k], $ra[$l]; " BEGIN { $^W = 1; } BEGIN { $/ = "\n"; $\ = "\n"; } use strict 'refs'; (my(@ra) = ('e', 'h', 'l', 'o')); (my($i, $j, $k, $l) = (0.99876, 1.00123, 2.499999, 3.5)); print($ra[$j], $ra[$i], $ra[$k], $ra[$k], $ra[$l]); -e syntax OK
      Dunno about the documentation.


      Give a man a fish:  <%-{-{-{-<

        ++ Thanks for the runtime examples, AnomalousMonk.

        "Dunno about the documentation."

        After much delving in that musty library beneath the lower catacombs, I believe I may have found an ancient scroll of particular relevance:

        $ perldoc perlglossary
        ...
            dwimmer
                DWIM is an acronym for “Do What I Mean”, the principle that something
                should just do what you want it to do without an undue amount of fuss.
                A bit of code that does “dwimming” is a “dwimmer”. Dwimming can
                require a great deal of behind-the-scenes magic, which (if it doesn’t
                stay properly behind the scenes) is called a dweomer instead.
        ...
        

        Perhaps, to avoid this dwimmer becoming a dweomer, we should stop poking it. :-)

        — Ken

Re^2: How it works?
by monorels (Novice) on Jan 20, 2016 at 19:30 UTC
    Thanks!
Re^2: How it works?
by monorels (Novice) on Jan 20, 2016 at 19:30 UTC
    Thanks!