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

why is
geuma@geuma:~$ perl -e 'for (1..5) { print "$_\n" };' 1 2 3 4 5
working, but not:
geuma@geuma:~$ perl -e 'for (5..1) { print "$_\n" };'
There is also no error or warning with that kind of code. I know, that there are a lot of ways to do this... but i think its strange ... is anybody able to explain this behavior

Replies are listed 'Best First'.
Re: max .. min does not work
by davorg (Chancellor) on Jul 23, 2008 at 16:15 UTC
Re: max .. min does not work
by broomduster (Priest) on Jul 23, 2008 at 16:13 UTC
    Because the range operator requires that the left operand is greater than the right operand. To count down, use reverse:

    perl -e 'for (reverse 1..5) {print "$_\n"};'

    Update: The left operand must be less than the right operand... :(

Re: max .. min does not work
by FunkyMonk (Bishop) on Jul 23, 2008 at 16:11 UTC
    If you want to see the list in reverse, use reverse:
    perl -e 'for (reverse 1..5) { print "$_\n" };'


    Unless I state otherwise, all my code runs with strict and warnings
Re: max .. min does not work
by olus (Curate) on Jul 23, 2008 at 16:19 UTC

    Above you have the answer you were looking for. But just out of curiosity, if you use the -l option, you won't need to add those \n to the print statements.

    perl -le 'for (1..5) { print "$_" };'
      Nor is it necessary to add "$_" to print, for that matter:
      perl -le 'for (1..5) { print };'

      Update: And golfing down a little more:

      perl -le 'print for(1..5)'
        Nor are the parentheses in this reversed form ;-)
        perl -le 'print for 1..5'
        Update: Of course, we could drop for too, but that won't help golfing: perl -le '$,=$/; print 1..5' :)

        :o) You are right of course. My intention was not to golf the code. It's just that I find that \n a bit messy, and thus just tried to show something a bit cleaner. But yours are pretty readable as well.

Re: max .. min does not work
by moritz (Cardinal) on Jul 23, 2008 at 16:16 UTC
    I seem to recall that range semantics are implemented in terms of ++, so this:
    for ($a .. $b) { ... }

    Should be roughly equivalent to

    for ($_ = $a; $_ <= $b; $_++) { ... }

    You see that with ($a, $b) = (5, 1) the body of the loop won't be executed. (For strings the comparison is le, not <=, I think).

    (update: added ++ where appropriate, Fletch++)

Re: max .. min does not work
by shmem (Chancellor) on Jul 23, 2008 at 23:24 UTC

    Strange it is, indeed... as others explained, end must be greater than start. You could use negative values to count down:

    perl -e 'for (-5..-1) { print -"$_\n" };' +5 +4 +3 +2 +1

    Leading pluses? Eh. That seems to be perl's way of saying it knows that double negation is affirmation... how strange... but on a second look, one learns that it has to do with the string resulting from the interpolation:

    perl -e 'for (-5..-1) { print -$_,"\n" };' 5 4 3 2 1

    A stringified number and a number-number are not always the same thing.. ;-)

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}