Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Perl Switch Errors on certain version

by minixman (Beadle)
on Nov 29, 2005 at 09:21 UTC ( [id://512548]=perlquestion: print w/replies, xml ) Need Help??

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

All i am use the switch module to in the example code below.
switch ($subkey) { case 1 {$acc = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: Account=$acc");}} case 11 {$ordid = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: OrderId=$ordid");} +} case 14 {$lotsfill = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: LotsFilled=$lotsfi +ll");}} case 31 {$fillprice = $messagebin{$file}{$subkey}; if($debug){ &writelog(3,"DEBUG: FillPrice=$fillpr +ice");}} case 32 {$lotsact = $messagebin{$file}{$subkey}; if($debug){ &writelog(3,"DEBUG: LotsActioned=$lot +sact");}} case 34 {$transno = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: TransNo=$transno") +;}} # As 35 can contain execution report, we make sur +e we can handle them. case 35 {my $new = $messagebin{$file}{$subkey}; if($new =~ m/D/i){$action = "New";if($debug){&wri +telog(3,"DEBUG: Action=$action");}} elsif($new =~ m/G/i){$action = "Amend";if($debug) +{&writelog(3,"DEBUG: Action=$action");}} elsif($new =~ m/F/i){$action = "Cancel";if($debug +){&writelog(3,"DEBUG: Action=$action");}} elsif($new =~ /9/){$action = "Reject";if($debug){ +&writelog(3,"DEBUG: Action=$action");}} elsif($new =~ /8/){$action = "Report";if($debug){ +&writelog(3,"DEBUG: Action=$action");}} } case 37 {$dborderid = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: DBOrderId=$dborder +id");}} case 38 {$lotsordered = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: LotsOrdered=$lotso +rdered");}} case 40 {$ordertype = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: OrderType=$orderty +pe");}} case 41 {$amedorderid = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: AmendOrderId=$amed +orderid");}} case 44 {$orderprice = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: OrderPrice=$orderp +rice");}} case 50 {$traderid = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: TraderId=$traderid +");}} case 54 {my $bs = $messagebin{$file}{$subkey}; if($bs == 1){$buysell = "Buy";if($debug){&writelo +g(3,"DEBUG: BuySell=$buysell");}} elsif($bs == 2){$buysell = "Sell";if($debug){&wri +telog(3,"DEBUG: BuySell=$buysell");}} } case 55 {$consid = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: Contract=$consid") +;}} case 100 {$exchange = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: Exchange=$exchange +");}} case 150 {my $new1 = $messagebin{$file}{$subkey}; if($new1 == 0){$filltype = "Ack";if($debug){&writ +elog(3,"DEBUG: Action=$action");}} elsif($new1 == /1/){$filltype = "Part Fill";if($d +ebug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /2/){$filltype = "Full Fill";if($d +ebug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /3/){$filltype = "Done for Day";if +($debug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /4/){$filltype = "Ack Cancel";if($ +debug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /5/){$filltype = "Ack Amend";if($d +ebug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /6/){$filltype = "Pending Cancel"; +if($debug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /7/){$filltype = "Stopped";if($deb +ug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /8/){$filltype = "Rejected";if($de +bug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 == /9/){$filltype = "Suspended";if($d +ebug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 =~ m/A/i){$filltype = "Pending new";i +f($debug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 =~ m/B/i){$filltype = "Calculated";if +($debug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 =~ m/C/i){$filltype = "Expired";if($d +ebug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 =~ m/D/i){$filltype = "Restated";if($ +debug){&writelog(3,"DEBUG: Action=$action");}} elsif($new1 =~ m/E/i){$filltype = "Pending Replac +e";if($debug){&writelog(3,"DEBUG: Action=$action");}} else{$filltype = "Unknown";if($debug){&writelog(3 +,"DEBUG: Action=$action");}} } case 151 {$lotsstillopen = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: LotsOpen=$lotsstil +lopen");}} case 200 {$maturity = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: Maturity=$maturity +");}} } }
Now the strange thing is when i run this on my OS X Tiger install with the default perl which i think if 5.8 i get no errors, and this is the machine i wrote it on. When i run this code on my gentoo box with
$ perl -v This is perl, v5.8.3 built for i686-linux
I get the following error.
$ perl engine_reader.pl Bad switch statement (problem in the code block?) near engine_reader.p +l line 214 (cuthbe@ferrari)-(08:51 AM Tue Nov 29)-(FIXReader) $

And if i try and use my activestate version on the gentoo machine, i get the same thing.

Replies are listed 'Best First'.
Re: Perl Switch Errors on certain version
by Corion (Patriarch) on Nov 29, 2005 at 09:31 UTC

    Do not use Switch.pm. It is a bad idea that has gone too far. Switch.pm will introduce hard-to-track bugs into your code by its mere presence. Use a simple table lookup or elsif-based dispatch instead. For further reference, see Categorized Damian Modules.

    In your case, you have two ways of progress - you need to decide which one suits your programming style or the problem better:

    if ($subkey == 1) { $acc = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: Account=$acc");} } elsif ($subkey == 11) { $ordid = $messagebin{$file}{$subkey}; if($debug){&writelog(3,"DEBUG: OrderId=$ordid"); } elsif ($subkey == 14) { ... } else { # you should _always_ have an else branch warn "Unhandled subkey value $subkey."; };

    or, if your subkeys are more of a tabular structure:

    my $acc; my %handler = ( 1 => sub { $acc = $messagebin{$file}{1}; }, 11 => sub { ... }, ); if (my $code = $handler{+$subkey}) { $code->($subkey); # I found it convenient to have the dispatch value # available in the dispatch handler } else { warn "Unhandled subkey value $subkey"; };

    In your case, you seem to be filling some data structure, so you might need to create the handler hash and the subroutines in a scope which sees the tables. This might or might not be convenient in your case.

      Hi Corion, I followed your suggestion and changed my code by removing switch statements to hash-key value loop; and i was thus able to convert my perl script to windows executable. Thanks for the tip :) I learned something new in Perl along the way. Regards, Mohit Vohra.
Re: Perl Switch Errors on certain version
by tirwhan (Abbot) on Nov 29, 2005 at 09:31 UTC

    Take a look at perldoc Switch, it says 'Due to the heuristic nature of Switch.pm's source parsing, the presence of regexes specified with raw "?...?" delimiters may cause mysterious errors. The workaround is to use "m?...?" instead.', You have a few of these matches in your code, for example

    elsif($new =~ /9/){$action = "Reject";if($debug){&writelog(3,"DEBUG: A +ction=$action");}}

    , I'd suggest you stick an "m" in front of that match and see whether that fixes the error.

    In general, read the caveats at the end of the perldoc carefully, Switch suffers from problems inherent in source filters, I would not use it in production code (and the original author does not recommend doing so either).


    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
      Take a look at perldoc Switch, it says 'Due to the heuristic nature of Switch.pm's source parsing, the presence of regexes specified with raw "?...?" delimiters may cause mysterious errors. The workaround is to use "m?...?" instead.', You have a few of these matches in your code, for example
      elsif($new =~ /9/){$action = "Reject";if($debug){&writelog(3,"DEBUG: A +ction=$action");}}
      Eh, I can't find any question marks in the code you quote. Perhaps you meant to quote some other code? Although I can't find any ?...? constructs in the code of the OP.
      Perl --((8:>*

        I believe the perldoc refers to the practice of using "/.../" for a match instead of "m/.../", regardless of the actual delimiting character used.


        Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Re: Perl Switch Errors on certain version
by broquaint (Abbot) on Nov 29, 2005 at 10:07 UTC
    If you're having problems with Switch you could always use Switch::Perlish instead e.g The syntax is slightly different because it's just standard perl code and ought to achieve the same result, but with less syntactical magic.
    HTH

    _________
    broquaint

Re: Perl Switch Errors on certain version
by serf (Chaplain) on Nov 29, 2005 at 11:57 UTC
    Scarey having to deal with all of those numbers! I trust that they are coming from data or an external program and not being generated elsewhere in the script, as they are a debugging unfriendly way to pass information!

    I second getting rid of the switch($subkey)

    There's no harm in using:

    if ( $subkey eq 1 ) { ... } elsif ( $subkey eq 11 ) { ... } ...
    Also, in the 150 block where you have:
    elsif($new1 == /1/){
    down to:
    elsif($new1 == /9/){
    What are you expecting the string to be and what trying to test? ... a text match anywhere on the string:
    elsif($new1 =~ /1/){
    or a test for the actual exact number?
    elsif($new1 eq 1){
    or something else? I did this test myself how it would act:
    #!/usr/bin/perl -w use strict; for my $new1 qw(1 11 a1a 1aa 001 010) { print "$new1 == /1/ : "; if ( $new1 == /1/ ) { print "YES\n"; } else { print "NO\n"; } print "-" x 10, $/; print "$new1 == 1 : "; if ( $new1 == 1 ) { print "YES\n"; } else { print "NO\n"; } print "-" x 10, $/; print "$new1 =~ /1/ : "; if ( $new1 =~ /1/ ) { print "YES\n"; } else { print "NO\n"; } print "-" x 10, $/; print "$new1 eq /1/ : "; if ( $new1 eq /1/ ) { print "YES\n"; } else { print "NO\n"; } print "-" x 10, $/; print "$new1 eq 1 : "; if ( $new1 eq 1 ) { print "YES\n"; } else { print "NO\n"; } print "=" x 10, $/; }
    and was quite surprised by the results!
    if ( $new1 == /1/ )
    actually fails with:
    Use of uninitialized value in pattern match (m//) at ./try.pl line 8.
    if $new1 *is* 1 but on the other hand SUCCEEDS if $new1 is "a1a" !!!
Re: Perl Switch Errors on certain version
by Perl Mouse (Chaplain) on Nov 29, 2005 at 11:12 UTC
    This doesn't solve your problem (which probably should be solved by a complete rewrite anyway), but I noticed a couple of conditions of the form: $new1 == /1/. Now, that's legal Perl, but are you really sure you want this? It would be true if $_ contains a 1 and $new equals 1, or if $_ doesn't contain a 1 and $new equals 0 (or the empty string, or is undefined).
    Perl --((8:>*

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (7)
As of 2024-04-19 16:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found