in reply to Re: How it works?
in thread How it works?

"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

Replies are listed 'Best First'.
Re^3: How it works?
by AnomalousMonk (Archbishop) on Jan 21, 2016 at 20:25 UTC

    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