Using switch

G

Gabkin

I want to use a switch .. case statement in my program.

I looked it up with 'perldoc switch' and found the help.
I tested some code from the perldoc switch help and it failed.
This is what I tried...

<PERL CODE>
use switch;
print("Enter a digit\n");
$var = <STDIN>; chop $var;
print("That digit was ".classify_digit($var)."\n");
exit;

sub classify_digit {
switch ($_[0]) {
case 0 { return 'zero' }
case [2,4,6,8] { return 'even' }
case [1,3,4,7,9] { return 'odd' }
case /[A-F]/i { return 'hex' }
case else { return 'other' }
}
}
</PERL CODE>

And this is the error message I got...

<TESTING...>
bash$ perl misc/test_switch.pm

Number found where operator expected at misc/test_switch.pm line 8, near
"case 0"
(Do you need to predeclare case?)
syntax error at misc/test_switch.pm line 7, near ") {"
syntax error at misc/test_switch.pm line 9, near "case ["
Execution of misc/test_switch.pm aborted due to compilation errors.
</TESTING...>

Using perl, v5.8.2 on Cygwin.

The code seems fine to me.

Why is this switch statement failing?

I have looked at the help and its not helping, I am copying the sample
code and its also failing.

What am I doing wrong here?
 
P

Paul Lalli

I want to use a switch .. case statement in my program.

I looked it up with 'perldoc switch' and found the help.
I tested some code from the perldoc switch help and it failed.
This is what I tried...

<PERL CODE>
use switch;
^
On my system, the module is Switch.pm, not switch.pm. Case matters.

print("Enter a digit\n");
$var = <STDIN>; chop $var;

not that it matters in this case, but you almost always want chomp()
rather than chop(). Look them up to see why.

Paul Lalli
 
G

Gabkin

Paul said:
^
On my system, the module is Switch.pm, not switch.pm. Case matters.





not that it matters in this case, but you almost always want chomp()
rather than chop(). Look them up to see why.

Paul Lalli

D'oh!

use Switch;
not
use switch;

Thanks, I feel stupid now.

as for looking up stuff (with perldoc) how do you search for stuff like
'chop' vs 'chomp'?

'perldoc chomp' gets me nowhere.

Is there a manual for the perl manual somewhere?
I can't find an obvious one anywhere...
 
J

Jürgen Exner

Gabkin said:
as for looking up stuff (with perldoc) how do you search for stuff
like 'chop' vs 'chomp'?

chop() and chomp() are functions, so you look for their manual pages by
specifying the -f option:
perldoc -f chop
perldoc -f chomp
'perldoc chomp' gets me nowhere.

Because chomp is neither a module nor a main document section.
Is there a manual for the perl manual somewhere?
I can't find an obvious one anywhere...

See "perldoc perldoc" for information about how to use perldoc and "perldoc
perl" about which manuals are available.

jue
 
P

Paul Lalli

D'oh!

use Switch;
not
use switch;

Thanks, I feel stupid now.

as for looking up stuff (with perldoc) how do you search for stuff like
'chop' vs 'chomp'?

'perldoc chomp' gets me nowhere.

Is there a manual for the perl manual somewhere?
I can't find an obvious one anywhere...

at the risk of causing you to feel stupid again, the manual for the manual
is, as you might expect:

perldoc perldoc

:)

In which, you should find the answer to the above question, which is that
to find documentation on a specific function, give the -f option:

perldoc -f chomp


Paul Lalli
 
A

Anno Siegel

Gabkin said:
D'oh!

use Switch;
not
use switch;

You have another error in your code. "case else" should be just "else".
as for looking up stuff (with perldoc) how do you search for stuff like
'chop' vs 'chomp'?

'perldoc chomp' gets me nowhere.

perldoc -f chomp
Is there a manual for the perl manual somewhere?

perldoc perldoc

Anno
 
G

Gabkin

Forgive me if this is another silly question, but is there a limit to
the number of 'case' statements that can be used in a switch block?

It certainly looks like there is...

If this is so, that's gonna suck, because I have 170+ conditions which
are perfect for a switch..case statement, a nested if..elsif..etc would
really be klunky!

Here is a (long) listing of what makes me suspect there is a finite
number of cases....
(forgive me if its excessively long)

<PERL SNIPPET FROM ACTUAL PROGRAM>
switch ($Dept_budget_code) {
case 'AECOI' { $temp = 'AS-ECO-I-2004'; }
case 'AECOM' { $temp = 'AS-ECO-M-2004'; }
case 'AECOP' { $temp = 'AS-ECO-P-2004'; }
case 'AENGI' { $temp = 'AS-ENG-I-2004'; }
case 'AENGM' { $temp = 'AS-ENG-M-2004'; }
case 'AENGP' { $temp = 'AS-ENG-P-2004'; }
case 'AGEOI' { $temp = 'AS-GEO-I-2004'; }
case 'AGEOM' { $temp = 'AS-GEO-M-2004'; }
case 'AGEOP' { $temp = 'AS-GEO-P-2004'; }
case 'AHISI' { $temp = 'AS-HIS-I-2004'; }
case 'AHISM' { $temp = 'AS-HIS-M-2004'; }
case 'AHISP' { $temp = 'AS-HIS-P-2004'; }
case 'APHII' { $temp = 'AS-PHI-I-2004'; }
case 'APHIM' { $temp = 'AS-PHI-M-2004'; }
case 'APHIP' { $temp = 'AS-PHI-P-2004'; }
case 'APLAI' { $temp = 'AS-PLA-I-2004'; }
case 'APLAM' { $temp = 'AS-PLA-M-2004'; }
case 'APLAP' { $temp = 'AS-PLA-P-2004'; }
case 'APOLI' { $temp = 'AS-POL-I-2004'; }
case 'APOLM' { $temp = 'AS-POL-M-2004'; }
}
</PERL SNIPPET>
(and there are another 150+ conditions which also need to be checked...)

This causes the following...

<BASH>
bash$ perl -c Program.pm
Bad switch statement (problem in the code block?) near Program.pm line 246
</BASH>

(its not on line 246, more like line 1050...)
(Also, its not really called Program.pm)

but when I delete 10 cases of that switch..case block so that it appears
like so...

<PERL SNIPPET>
switch ($Dept_budget_code) {
case 'AHISM' { $temp = 'AS-HIS-M-2004'; }
case 'AHISP' { $temp = 'AS-HIS-P-2004'; }
case 'APHII' { $temp = 'AS-PHI-I-2004'; }
case 'APHIM' { $temp = 'AS-PHI-M-2004'; }
case 'APHIP' { $temp = 'AS-PHI-P-2004'; }
case 'APLAI' { $temp = 'AS-PLA-I-2004'; }
case 'APLAM' { $temp = 'AS-PLA-M-2004'; }
case 'APLAP' { $temp = 'AS-PLA-P-2004'; }
case 'APOLI' { $temp = 'AS-POL-I-2004'; }
case 'APOLM' { $temp = 'AS-POL-M-2004'; }
}
</PERL SNIPPET>

it works!

<BASH>
bash$ perl -c Program.pm
Program.pm syntax OK
</BASH>

All of the lines are identical except for the text enclosed in quotes,
so I don't think theres a bad line.

It doesn't seem to matter which ten lines I delete, which is odd.

I couldnt find any mention of a limit to 'case' statements in the
documentation.
 
B

Brad Baxter

<PERL SNIPPET FROM ACTUAL PROGRAM>
switch ($Dept_budget_code) {
case 'AECOI' { $temp = 'AS-ECO-I-2004'; }
case 'AECOM' { $temp = 'AS-ECO-M-2004'; }
case 'AECOP' { $temp = 'AS-ECO-P-2004'; }
case 'AENGI' { $temp = 'AS-ENG-I-2004'; }
case 'AENGM' { $temp = 'AS-ENG-M-2004'; }
case 'AENGP' { $temp = 'AS-ENG-P-2004'; }
case 'AGEOI' { $temp = 'AS-GEO-I-2004'; }
case 'AGEOM' { $temp = 'AS-GEO-M-2004'; }
case 'AGEOP' { $temp = 'AS-GEO-P-2004'; }
case 'AHISI' { $temp = 'AS-HIS-I-2004'; }
case 'AHISM' { $temp = 'AS-HIS-M-2004'; }
case 'AHISP' { $temp = 'AS-HIS-P-2004'; }
case 'APHII' { $temp = 'AS-PHI-I-2004'; }
case 'APHIM' { $temp = 'AS-PHI-M-2004'; }
case 'APHIP' { $temp = 'AS-PHI-P-2004'; }
case 'APLAI' { $temp = 'AS-PLA-I-2004'; }
case 'APLAM' { $temp = 'AS-PLA-M-2004'; }
case 'APLAP' { $temp = 'AS-PLA-P-2004'; }
case 'APOLI' { $temp = 'AS-POL-I-2004'; }
case 'APOLM' { $temp = 'AS-POL-M-2004'; }
}
</PERL SNIPPET>
(and there are another 150+ conditions which also need to be checked...)

In this case I wouldn't use Switch. I'd use a hash.

my %budget_codes = (
'AECOI' => 'AS-ECO-I-2004',
'AECOM' => 'AS-ECO-M-2004',
'AECOP' => 'AS-ECO-P-2004',
'AENGI' => 'AS-ENG-I-2004',
'AENGM' => 'AS-ENG-M-2004',
'AENGP' => 'AS-ENG-P-2004',
'AGEOI' => 'AS-GEO-I-2004',
'AGEOM' => 'AS-GEO-M-2004',
'AGEOP' => 'AS-GEO-P-2004',
'AHISI' => 'AS-HIS-I-2004',
'AHISM' => 'AS-HIS-M-2004',
'AHISP' => 'AS-HIS-P-2004',
'APHII' => 'AS-PHI-I-2004',
'APHIM' => 'AS-PHI-M-2004',
'APHIP' => 'AS-PHI-P-2004',
'APLAI' => 'AS-PLA-I-2004',
'APLAM' => 'AS-PLA-M-2004',
'APLAP' => 'AS-PLA-P-2004',
'APOLI' => 'AS-POL-I-2004',
'APOLM' => 'AS-POL-M-2004',
);

$temp = $budget_codes{ $Dept_budget_code };


Regards,

Brad
 
J

Jürgen Exner

Gabkin wrote:
[...]
Here is a (long) listing of what makes me suspect there is a finite
number of cases....
(forgive me if its excessively long)

<PERL SNIPPET FROM ACTUAL PROGRAM>
switch ($Dept_budget_code) {
case 'AECOI' { $temp = 'AS-ECO-I-2004'; }
case 'AECOM' { $temp = 'AS-ECO-M-2004'; }
case 'AECOP' { $temp = 'AS-ECO-P-2004'; }
case 'AENGI' { $temp = 'AS-ENG-I-2004'; }
[...]

Ouch, what an ugly code! This screams for using a hash:

my %table= (
'AECOI' => 'AS-ECO-I-2004';
'AECOM' => 'AS-ECO-M-2004';
'AECOP' => 'AS-ECO-P-2004';
'AENGI' => 'AS-ENG-I-2004';
[...]
}

And then your whole nightmare collapses into one trivial assignment:

$temp = $table{$Dept_budget_code};

jue
 
P

Paul Lalli

Forgive me if this is another silly question, but is there a limit to
the number of 'case' statements that can be used in a switch block?

It certainly looks like there is...

If this is so, that's gonna suck, because I have 170+ conditions which
are perfect for a switch..case statement, a nested if..elsif..etc would
really be klunky!

Here is a (long) listing of what makes me suspect there is a finite
number of cases....
(forgive me if its excessively long)

<PERL SNIPPET FROM ACTUAL PROGRAM>
switch ($Dept_budget_code) {
case 'AECOI' { $temp = 'AS-ECO-I-2004'; }
case 'AECOM' { $temp = 'AS-ECO-M-2004'; }
case 'AECOP' { $temp = 'AS-ECO-P-2004'; }
case 'AENGI' { $temp = 'AS-ENG-I-2004'; }

}
</PERL SNIPPET>
(and there are another 150+ conditions which also need to be checked...)


Is this really what the code is? Is the pattern really that simple? If
so, why on earth are you typing 170+ conditions?

$temp = substr($code,0,1) .
'S-' .
substr($code,1,3) .
'-' .
substr($code,4,1) .
'-2004';

That one expression would dissect your budget code and create the proper
temp string. Gurus around here can probably even suggest better looking
ways of doing that (perhaps splitting $code on the null string and using
array indices rather than three separate calls to substr).

This causes the following...

<BASH>
bash$ perl -c Program.pm
Bad switch statement (problem in the code block?) near Program.pm line 246
</BASH>

(its not on line 246, more like line 1050...)
(Also, its not really called Program.pm)

but when I delete 10 cases of that switch..case block so that it appears
like so...

it works!
All of the lines are identical except for the text enclosed in quotes,
so I don't think theres a bad line.

It doesn't seem to matter which ten lines I delete, which is odd.

I couldnt find any mention of a limit to 'case' statements in the
documentation.

The documentation for Switch.pm says nothing about how many cases
you can have. It does however, contain this statement:
"If your source file is longer then 1 million characters and you have a
switch statement that crosses the 1 million (or 2 million, etc.) character
boundary you will get mysterious errors. The workaround is to use smaller
source files."
That doesn't apply to you, does it?

Paul Lalli
 
G

Gabkin

Paul said:
Is this really what the code is? Is the pattern really that simple? If
so, why on earth are you typing 170+ conditions?

$temp = substr($code,0,1) .
'S-' .
substr($code,1,3) .
'-' .
substr($code,4,1) .
'-2004';

That one expression would dissect your budget code and create the proper
temp string. Gurus around here can probably even suggest better looking
ways of doing that (perhaps splitting $code on the null string and using
array indices rather than three separate calls to substr).

Unfortunately, the pattern isn't that simple. There are over 170
combinations to be checked and the desired output for all of them aren't
as clearcut as the snippet of a snippet you considered.
consider this sample...
GWWWS --> SP-HOLD-2003

I really have thought about that route and discarded it. A switch..case
really is the best for this in terms of simplicity and maintainability.
It won't produce the shortest quickest code, but I'm not playing 'perl
golf'.
Also the specification may come under further revision/changes, which a
switch..case statement would make easy to update.

Furthermore I'm not typing out 170+ combinations, I would have shot
myself by now if I had to...
I copied the MS-word table (which this came from) into a text file and
used vi's search/replace to insert valid perl code.
The documentation for Switch.pm says nothing about how many cases
you can have. It does however, contain this statement:
"If your source file is longer then 1 million characters and you have a
switch statement that crosses the 1 million (or 2 million, etc.) character
boundary you will get mysterious errors. The workaround is to use smaller
source files."
That doesn't apply to you, does it?

Paul Lalli
Nope.

wc Program.pm
1239 6485 48164 Program.pm

1239 Lines, 48164 characters.
Nowhere near 1 million characters!
 
G

Gabkin

Brad said:
In this case I wouldn't use Switch. I'd use a hash.

my %budget_codes = (
'AECOI' => 'AS-ECO-I-2004',
'AECOM' => 'AS-ECO-M-2004',
'AECOP' => 'AS-ECO-P-2004',
'AENGI' => 'AS-ENG-I-2004',
'AENGM' => 'AS-ENG-M-2004',
'AENGP' => 'AS-ENG-P-2004',
'AGEOI' => 'AS-GEO-I-2004',
'AGEOM' => 'AS-GEO-M-2004',
'AGEOP' => 'AS-GEO-P-2004',
'AHISI' => 'AS-HIS-I-2004',
'AHISM' => 'AS-HIS-M-2004',
'AHISP' => 'AS-HIS-P-2004',
'APHII' => 'AS-PHI-I-2004',
'APHIM' => 'AS-PHI-M-2004',
'APHIP' => 'AS-PHI-P-2004',
'APLAI' => 'AS-PLA-I-2004',
'APLAM' => 'AS-PLA-M-2004',
'APLAP' => 'AS-PLA-P-2004',
'APOLI' => 'AS-POL-I-2004',
'APOLM' => 'AS-POL-M-2004',
);

$temp = $budget_codes{ $Dept_budget_code };


Regards,

Brad

On hindsight, this is a much better idea than using switch.
Thanks Brad (and Jurgen Exner who suggested the same).

However I am still puzzled by why the switch..case failed.
 
S

Sherm Pendley

Jürgen Exner said:
Ouch, what an ugly code! This screams for using a hash:

my %table= (
'AECOI' => 'AS-ECO-I-2004';
'AECOM' => 'AS-ECO-M-2004';
'AECOP' => 'AS-ECO-P-2004';
'AENGI' => 'AS-ENG-I-2004';
[...]
}

Good idea, bad example. I think you want to use commas in the middle, not
semicolons. And end the statement with a semicolon:

my %table = (
'AECOI' => 'AS-ECO-I-2004',
'AECOM' => 'AS-ECO-M-2004',
[...]
};

sherm--
 
S

Sherm Pendley

Gabkin said:
I copied the MS-word table (which this came from) into a text file and
used vi's search/replace to insert valid perl code.

In that case (ouch, bad pun...), you might want to look through the "bad"
lines for "smart" quotes or other Word-isms.

sherm--
 
G

Gabkin

Sherm said:
Gabkin wrote:




In that case (ouch, bad pun...), you might want to look through the "bad"
lines for "smart" quotes or other Word-isms.

sherm--
Already done, thanks.

If I had my way, all typed digital communication would be in HTML or
straight ASCII format.

Viva ASCII!

....
and that was quite a cheap pun.
;)
 
J

John J. Trammell

Good idea, bad example. I think you want to use commas in the middle,
not semicolons. And end the statement with a semicolon:

my %table = (
'AECOI' => 'AS-ECO-I-2004',
'AECOM' => 'AS-ECO-M-2004',
[...]
};
^

Surely you mean ");"...
 
J

Jürgen Exner

Sherm said:
Jürgen Exner said:
Ouch, what an ugly code! This screams for using a hash:

my %table= (
'AECOI' => 'AS-ECO-I-2004';
'AECOM' => 'AS-ECO-M-2004';
'AECOP' => 'AS-ECO-P-2004';
'AENGI' => 'AS-ENG-I-2004';
[...]
}

Good idea, bad example. I think you want to use commas in the middle,
not semicolons. And end the statement with a semicolon:

my %table = (
'AECOI' => 'AS-ECO-I-2004',
'AECOM' => 'AS-ECO-M-2004',
[...]
};

Well, yeah, too much copy-n-paste.
Obviously that "code"-snipped was never meant to be run directly but only to
give the OP an idea of how he can simplify his code by using a hash.

jue
 
J

Jürgen Exner

Gabkin said:
If I had my way, all typed digital communication would be in HTML or
straight ASCII format.

So, you mean to either exclude the vast majority of people in the world from
(at least written) digital communication or to have them giving up their
cultural identity (which to a very large part is defined by language) and
use ASCII characters only?
This presumptious (or maybe just ignorant) attitude was and is the reason
for so many problems regarding global software and I thought it finally died
many years ago. Guess I was wrong.

jue
 
G

Gabkin

Jürgen Exner said:
So, you mean to either exclude the vast majority of people in the world from
(at least written) digital communication or to have them giving up their
cultural identity (which to a very large part is defined by language) and
use ASCII characters only?
This presumptious (or maybe just ignorant) attitude was and is the reason
for so many problems regarding global software and I thought it finally died
many years ago. Guess I was wrong.

jue
You're right, of course.

I spoke hastily because I dislike the prevalence of MS-word
documents/pdf files/etc.IMHO html and straight text are the preferred
methods of communication for digital text.I didn't mean to exclude the
non-english world from communicating.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top