Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Switch - "case" may clash with future reserved word

by ahoffmann (Initiate)
on Nov 28, 2007 at 17:17 UTC ( [id://653585]=perlquestion: print w/replies, xml ) Need Help??

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

I am using switch statements in a couple subroutines located in the same script. In the first subroutine I have a few switch statements. Here is one example:
switch ( $time ) { case "30days" { $caption .= "Past 30 Days"; } case "3mons" { $caption .= "Past 3 Months"; } case "1yr" { $caption .= "Past 1 Year"; } case "all" { $caption .= "All Data"; } }
These statements worked fine until I added a second subroutine and duplicated the switch statements verbatim. Now I am receiving the following compiler errors:
Unquoted string "case" may clash with future reserved word at ./genera +te_xml.pl_edit line 615. String found where operator expected at ./generate_xml.pl_edit line 61 +5, near "case "all"" (Do you need to predeclare case?) Unquoted string "case" may clash with future reserved word at ./genera +te_xml.pl_edit line 618. String found where operator expected at ./generate_xml.pl_edit line 61 +8, near "case "regular"" (Do you need to predeclare case?) syntax error at ./generate_xml.pl_edit line 614, near ") {" syntax error at ./generate_xml.pl_edit line 618, near "case "regular""
These are all referencing a switch statement in the second subroutine. I have scoured my code and cannot find any syntax errors that would cause these errors. (I especially looked around line 614, but there is nothing different. It has been copied verbatim from the first subroutine.) I have included use Switch;. Any suggestions?

Replies are listed 'Best First'.
Re: Switch - "case" may clash with future reserved word
by Fletch (Bishop) on Nov 28, 2007 at 17:29 UTC
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Switch - "case" may clash with future reserved word
by wind (Priest) on Nov 28, 2007 at 17:34 UTC
    I would also strongly recommend against ever using switches. Most often a better construct is available, such as a lookup table for the above example:
    my %time_captions = ( 30days => "Past 30 Days", 3mons => "Past 3 Months"; 1yr => "Past 1 Year", all => "All Data", }; $caption .= $time_captions{$time};
    - Miller
Re: Switch - "case" may clash with future reserved word
by moritz (Cardinal) on Nov 28, 2007 at 17:30 UTC
    Maybe you could provide a code examples that actually shows these failures?

    BTW perl 5.10 (to be released before christmas) comes with built in switch statement of the form

    given ($time) { when ("30days"){ ... } ... default { # do something else } }
Re: Switch - "case" may clash with future reserved word
by tuxz0r (Pilgrim) on Nov 28, 2007 at 18:24 UTC
    Fletch makes a good point about Switch, but if you need to fake it and make it look like a switch (although the lookup example is succinct and readable), you could do this, which I've done in the past:
    for ($var) { /cat/ && do { ...; last }; /dog/ && do { ...; last }; warn "$var Nothing matched\n"; }
    Pretty basic, and it has a similar feel. Just use the for to assign the value to $_ and then use pattern matching for your "case"s. Kind of similar to the shell's case ... in syntax. However, coding it as a lookup, or using some other idiom is usually a better bet.

    ---
    echo S 1 [ Y V U | perl -ane 'print reverse map { $_ = chr(ord($_)-1) } @F;'
    Warning: Any code posted by tuxz0r is untested, unless otherwise stated, and is used at your own risk.

Re: Switch - "case" may clash with future reserved word
by ikegami (Patriarch) on Nov 28, 2007 at 20:38 UTC

    That's exactly the message I get when I don't use use Switch; Switch doesn't detect your code as being a switch statement, probably due to something elsewhere in the program. Source filters are fragile.

    Remove bits of the program until perl -c script.pl no longer gives the error. The last bit of code you removed likely contains the code Switch has a problem with.

    I know that some functions of Text::Balanced (used by many source filters including Switch) have problems with //, although I don't know if it'll result in this problem, though. split(//, $var, -1) can be replaced with $var =~ /(.)/sg.

      I've seen other brittleness with it interpreting random "s"s in text when trying to parse for quotelike strings. Apparently it gets to thinking thinking it's the start of some form of a s/// statement and gets massively confuzzled with the crashing and the syntax errors and the GLEIVEN!

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: Switch - "case" may clash with future reserved word
by ahoffmann (Initiate) on Nov 28, 2007 at 21:50 UTC
    Thanks for the helpful advice, everyone. I'll just use something other than switch. (Didn't realize the module was so buggy.) The hash lookup example seems like the best fix. Thanks for the suggestion!
      I wouldn't say Switch.pm is buggy (update: in this specific case).

      It is a very simplistic source-filter, which gives you plenty of warning in its documentation on the risks and limits of its use.

      A "dispatch table" (as the hash of subs is usually called) is indeed a very useful construct, but sometimes a real switch/case-like construct is better.

      For example, if your algorithm calls for falling through from one case to another, it's hard to achieve that cleanly with a dispatch table (without additional external machinery).

      As mentioned above, Perl 5.10 (and 6) will introduce the given/when construct, which works like switch/case but is more powerful. The switch/case construct in most languages allows only integer or scalar values in case expressions, but given/when will allow many more possibilities (by using the "smart match" operator). Example:

      given $data { when /^\d+$/ { return %var{""} = $_ } when 'previous' { return %var{""} // fail NoData } when %var { return %var{""} = %var{$_} } default { die Err::BadData : msg=>"Don't understand $_" } }
      I know I'll be using it with abandon as soon as 5.10 comes out :-)

      -David

      I found this problem today where I was having 3 'switch' statements and error was coming after the Ist one. And a random workaround for me was to use 'use Switch' everytime before each switch statements. I was using perl 5.8.8. But its good to know the erratic behaviour. -dpk
Re: Switch - "case" may clash with future reserved word
by tachyon-II (Chaplain) on Nov 29, 2007 at 06:40 UTC

    I usually use this idiom to emmulate a case statement in Perl. Easy enough to write and read IMHO.

    $caption .= $time eq "30days" ? "Past 30 Days" : $time eq "3mons" ? "Past 3 Months": $time eq "1yr" ? "Past 1 Year" : $time eq "all" ? "All Data" : "FALL_THROUGH_DEFAULT";

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-24 02:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found