in reply to Re^4: fall through switch/case in perl
in thread fall through switch/case in perl

Yes — doy. Execution does fall through to the next condition, but I missed the fact that that alone doesn't make the condition true. Out of my mind, back in five minutes.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re^6: fall through switch/case in perl
by tachyon (Chancellor) on Sep 07, 2004 at 00:49 UTC
    s/==/>=/g and it falls through ie
    for ( $var ) { $_ >= 10 and print "a"; $_ >= 9 and print "b"; $_ >= 8 and print "c"; $_ >= 7 and print "d"; $_ >= 6 and print "e"; $_ >= 5 and print "f"; $_ >= 4 and print "g"; $_ >= 3 and print "h"; $_ >= 2 and print "i"; $_ >= 1 and print "j"; }

    cheers

    tachyon

      While Aristotle posted a solution that more closely approximates the switch/case behavior, but - aside from the additional tests - isn't yours the better way to do it in Perl (meaning that it's a hell of a lot more readable as the number of cases grows)?

      Or what about:

      $accum = ''; for ( $var ) { if ( $_ < 1 ) { last; } else { $accum = 'j'.$accum; } if ( $_ < 2 ) { last; } else { $accum = 'i'.$accum; } if ( $_ < 3 ) { last; } else { $accum = 'h'.$accum; } if ( $_ < 4 ) { last; } else { $accum = 'g'.$accum; } if ( $_ < 5 ) { last; } else { $accum = 'f'.$accum; } if ( $_ < 6 ) { last; } else { $accum = 'e'.$accum; } if ( $_ < 7 ) { last; } else { $accum = 'd'.$accum; } if ( $_ < 8 ) { last; } else { $accum = 'c'.$accum; } if ( $_ < 9 ) { last; } else { $accum = 'b'.$accum; } $accum = 'a'.$accum; }
      Wouldn't that be similar, but provide a shortcut out (so we don't always run ten tests)? Also, push-ing onto an array and join-ing it at the end might be a little more flexible than the . operator...

      Just musing (as usual)...

      --J

      Update: The examples using goto further down are even faster (fewer tests) and preserve the fallthrough and the ability to execute arbitrary code in each case (rather than literally doing string manipulation), but you get an earful from purists when you use goto. :-)

        Personally I think that given perl has for, foreach, do, while, until, map, grep and all sorts of other operators that the case statement should have been part of the language from the start. You don't *need* it. In fact you don't need for or while or.... All you really need is goto and if which is how it gets implmented in assembler anyway, but that is hardly the point....

        cheers

        tachyon

      Yes, but that's not equivalent to the OP's code.

      Makeshifts last the longest.

        As you say, it is not equivalent. To do that you need some extra checks at the top of the 'loop' ie

        last unless /^\d+$/ and $_ <= 10;

        It is almost certainly a silly way to do it in Perl anyway. It is even a rather suboptimal way to do it in C.....

        for(i=0;i<var;i++) printf( "%c", 97+i ); /* C or perl */ print map chr,97..96+$var;

        cheers

        tachyon