Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^3: fall through switch/case in perl

by BrowserUk (Patriarch)
on Sep 07, 2004 at 01:46 UTC ( [id://388907]=note: print w/replies, xml ) Need Help??


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

The eval isn't required (unless I missed a subtlety?)

#! perl -sw use strict; my $var = 7; goto 'CASE'.($var+0); die "$var out of range"; 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"; __END__ P:\test>junk defghij

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

Replies are listed 'Best First'.
Re^4: fall through switch/case in perl
by etcshadow (Priest) on Sep 07, 2004 at 02:52 UTC
    The eval is necessary if you want to fully emulate the C semantic of not dieing if there is no matching case. Really, the full-on computed goto method (I should have just written this into my top-level response) is this (I think):
    { 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"; DEFAULT: }
    Which, admittedly, is not very different from Aristotle's. The only real difference being the outter braces. The purpose of them is to avoid polluting the label name-space. (Also, I prefer the "goto X or goto DEFAULT" over the "goto X; goto DEFAULT" purely for aesthetic reasons. :-D)

    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 too C-ish or something).

    ------------ :Wq Not an editor command: Wq

      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


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        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?
        No, I'm saying that goto $label dies if the label has not been defined. That is not how it works in C. In C, if you have not provided a case that matches your switch value, it jumps to the default case. That's why there's an eval, to prevent the die (not warning).
        [sstone@granite sstone]$ perl -le 'print 1; goto "FOO"; print 2' 1 Can't find label FOO at -e line 1. [sstone@granite sstone]$
        As far as preventing a warning on undef, well... I'd imagine that that should fit into whatever scheme you are using around undefs: warn if you have undef warnings on, else not. And there's nothing about stringifying $var that changes that semantic, so all seems well and good with my method.
        ------------ :Wq Not an editor command: Wq

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://388907]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2024-04-19 09:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found