in reply to Re^4: fall through switch/case in perl
in thread fall through switch/case in perl
Hmm. I think what your saying is that the eval is necessary to avoid a warning if $var doesn't contain a value for which there is a label defined?
If so, then it still doesn't handle the case where $var is undefined.
That can be handled by using a do BLOCK construct to disable warnings and adding a CASE0:
for my $var ( undef, 1 .. 10, 'fred' ) { goto 'CASE' . do{ local $^W; $var + 0 }; CASE10: print "a"; CASE9: print "b"; CASE8: print "c"; CASE7: print "d"; CASE6: print "e"; CASE5: print "f"; CASE4: print "g"; CASE3: print "h"; CASE2: print "i"; CASE1: print "j"; print "\n"; CASE0: }
I sort of wonder why this isn't given as one of the ways of achieving C-like switch statement behavior in the perl docs? Oh, well... it's probably horribly inefficient or something (apart from just being to C-ish or something).
C-ish it may be (though that's not a good reason in my book if it is clearer), but inefficient it is not:
P:\test>388915 ?> 1..10 Testing for vals [1..10] Rate if_cascade and_cascade goto_do goto_eval + goto if_cascade 11395/s -- -2% -11% -26% + -26% and_cascade 11627/s 2% -- -9% -24% + -25% goto_do 12845/s 13% 10% -- -17% + -17% goto_eval 15389/s 35% 32% 20% -- + -0% goto 15423/s 35% 33% 20% 0% + -- ?>
Benchmark/results
#! perl -sw use strict; use Benchmark qw[ cmpthese ]; our $DEBUG ||=0; our $ITERS = $DEBUG ? 1 : -3; $DEBUG or open STDOUT, '> :raw', \my( $mem ) or die $!; my $tests = { goto_eval => q[ $DEBUG and print "\ngoto_eval\n"; for my $var ( @inputs ) { eval { goto "CASE$var" } or goto DEFAULT; CASE10: print "a"; CASE9: print "b"; CASE8: print "c"; CASE7: print "d"; CASE6: print "e"; CASE5: print "f"; CASE4: print "g"; CASE3: print "h"; CASE2: print "i"; CASE1: print "j"; print "\n"; DEFAULT: } ], goto_do => q[ $DEBUG and print "\ngoto_do\n"; for my $var ( @inputs ) { goto 'CASE' . do{ local $^W; $var + 0 }; CASE10: print "a"; CASE9: print "b"; CASE8: print "c"; CASE7: print "d"; CASE6: print "e"; CASE5: print "f"; CASE4: print "g"; CASE3: print "h"; CASE2: print "i"; CASE1: print "j"; print "\n"; CASE0: } ], goto => q[ $DEBUG and print "\ngoto\n"; for my $var ( @inputs ) { goto 'CASE' . ($var + 0); CASE10: print "a"; CASE9: print "b"; CASE8: print "c"; CASE7: print "d"; CASE6: print "e"; CASE5: print "f"; CASE4: print "g"; CASE3: print "h"; CASE2: print "i"; CASE1: print "j"; print "\n"; CASE0: } ], if_cascade => q[ $DEBUG and print "\nif_cascade\n"; for my $var ( @inputs ) { for my $val ( $var ) { print "a" if ( $val >= 10 ); print "b" if ( $val >= 9 ); print "c" if ( $val >= 8 ); print "d" if ( $val >= 7 ); print "e" if ( $val >= 6 ); print "f" if ( $val >= 5 ); print "g" if ( $val >= 4 ); print "h" if ( $val >= 3 ); print "i" if ( $val >= 2 ); print "j" if ( $val >= 1 ); } print "\n"; } ], and_cascade => q[ $DEBUG and print "\nand_cascade\n"; for my $var ( @inputs ) { 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"; } print "\n"; } ], }; print STDERR '?> '; while( <STDIN> ) { chomp; warn "Testing for vals [$_]\n"; our @inputs = eval; cmpthese $ITERS, $tests; print STDERR '?> '; } __END__ P:\test>388915 ?> 1..10 Testing for vals [1..10] Rate if_cascade and_cascade goto_do goto_eval + goto if_cascade 11395/s -- -2% -11% -26% + -26% and_cascade 11627/s 2% -- -9% -24% + -25% goto_do 12845/s 13% 10% -- -17% + -17% goto_eval 15389/s 35% 32% 20% -- + -0% goto 15423/s 35% 33% 20% 0% + -- ?> P:\test>388915 -DEBUG=1 ?> 1..10, 'fred', undef Testing for vals [1..10, 'fred', undef] and_cascade j ij hij ghij fghij efghij defghij cdefghij bcdefghij abcdefghij Argument "fred" isn't numeric in numeric ge (>=) at (eval 5) line 5, < +STDIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 5, <STD +IN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 6, <STD +IN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 7, <STD +IN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 8, <STD +IN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 9, <STD +IN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 10, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 11, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 12, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 13, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 5) line 14, <ST +DIN> line 1. (warning: too few iterations for a reliable count) goto j ij hij ghij fghij efghij defghij cdefghij bcdefghij abcdefghij Use of uninitialized value in addition (+) at (eval 7) line 4, <STDIN> + line 1. (warning: too few iterations for a reliable count) goto_do j ij hij ghij fghij efghij defghij cdefghij bcdefghij abcdefghij (warning: too few iterations for a reliable count) goto_eval j ij hij ghij fghij efghij defghij cdefghij bcdefghij abcdefghij Use of uninitialized value in concatenation (.) or string at (eval 11) + line 4, <STDIN> line 1. (warning: too few iterations for a reliable count) if_cascade j ij hij ghij fghij efghij defghij cdefghij bcdefghij abcdefghij Use of uninitialized value in numeric ge (>=) at (eval 13) line 5, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 6, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 7, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 8, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 9, <ST +DIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 10, <S +TDIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 11, <S +TDIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 12, <S +TDIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 13, <S +TDIN> line 1. Use of uninitialized value in numeric ge (>=) at (eval 13) line 14, <S +TDIN> line 1. (warning: too few iterations for a reliable count) Rate goto_do and_cascade goto_eval goto +if_cascade goto_do 1000000000000000/s -- 0% 0% 0% + 0% and_cascade 1000000000000000/s 0% -- 0% 0% + 0% goto_eval 1000000000000000/s 0% 0% -- 0% + 0% goto 1000000000000000/s 0% 0% 0% -- + 0% if_cascade 1000000000000000/s 0% 0% 0% 0% + -- ?> ^Z
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^6: fall through switch/case in perl
by etcshadow (Priest) on Sep 07, 2004 at 05:44 UTC | |
by BrowserUk (Patriarch) on Sep 07, 2004 at 05:57 UTC | |
by etcshadow (Priest) on Sep 07, 2004 at 06:34 UTC | |
by BrowserUk (Patriarch) on Sep 07, 2004 at 06:53 UTC | |
by etcshadow (Priest) on Sep 07, 2004 at 19:11 UTC | |
| |
by Anonymous Monk on Sep 07, 2004 at 08:43 UTC | |
by Beechbone (Friar) on Sep 08, 2004 at 13:59 UTC |