Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Switch Module vs 'for' switch method 5

Status
Not open for further replies.

1DMF

Programmer
Joined
Jan 18, 2005
Messages
8,795
Location
GB
Hello, I was looking for a select case or switch for PERL and it seems there is no built in command for this, I did a search and found two possibilities.

1. Use the Switch module
Code:
use Switch;	
switch ($val) {		
         case 1		{ print "number 1" }
		case "a"	{ print "string a" }
		case [1..10,42]	{ print "number in list" }
		case (@array)	{ print "number in list" }
		case /\w+/	{ print "pattern" }
		case qr/\w+/	{ print "pattern" }
		case (%hash)	{ print "entry in hash" }
		case (\%hash)	{ print "entry in hash" }
		case (\&sub)	{ print "arg to subroutine" }
		else		{ print "previous case not true" }
	}

2. use a for command...like so
Code:
SWITCH: for ($where) {
               /In Card Names/     && do { push @flags, '-e'; last; };
               /Anywhere/          && do { push @flags, '-h'; last; };
               /In Rulings/        && do {                    last; };
               die "unknown value for form variable where: `$where'";
           }

Which is best, what's the overhead of invoking the switch module compared to using a for?

what would you use?

regards,

1DMF.

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Offhand, I don't know which is better (don't think I've every actually used the Switch module). If it's purely execution speed you're looking to measure, you could set up a benchmark using Benchmark or Benchmark::Timer.
 
it was really a curiosity thing, i've never needed a case/select type command before, I did some research and found those 2 ways of doing it.

I've been bitten before impelementing code examples I find on the web when they were bad/invalid/non-standard ways of doing something, like not using CGI to parse variables (i've already beat myslef up over that one!).
[hammer]

So before I steamed ahead , I thought I'd get some feedback, although for a working script I decided to go with
for ($where) {
/In Card Names/ && do { push @flags, '-e'; last; };
/Anywhere/ && do { push @flags, '-h'; last; };
/In Rulings/ && do { last; };
die "unknown value for form variable where: `$where'";
}
for my get_img program....
Code:
#!/usr/bin/perl

######################
# Set Error Trapping #
######################

use CGI::Carp qw(fatalsToBrowser warningsToBrowser); 
use warnings;
use strict;

##################
# use CGI Module #
##################
use CGI;

# Read URL data.
my $cgi = new CGI;

# Set img variable
my $img  = $cgi->param('IMG');

# Work out extension
my ($fn,$ext) = split(/\./, $img);
$ext = lc($ext);

# Check file type and print relevant MIME header
for ($ext) {
             /jpg/     && do { print "Content-type: image/jpeg\n\n"; last; };
             /gif/     && do { print "Content-type: image/gif\n\n"; last; };
             /png/     && do { print "Content-type: image/jpeg\n\n"; last; };
             die "Invalid image file type: `$ext'";
}

# Set full path to file
my $file = "PATH_TO_IMAGES/$fn.$ext";

# Open Image File
open(FILE, "<$file") || die "Error opening image file, seek support!";

# Prepare STDOUT for binary data
binmode(STDOUT);

# Print File
print <FILE>;
close(FILE);

}
It seems to work great so, maybe there is no point in using the Switch module.

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Using CGI to parse variables but not for printing headers? ;-)

I'd normally use a hash for something like this. Not necessarily the best way, but it gives you another option:

Code:
my %content_types = (
   jpg => 'image/jpeg',
   gif => 'image/gif',
   png => 'image/png'
);

if ( $content_types{ $ext } ) {
   print $cgi->header( $content_types{ $ext } );
}
else {
   die "Invalid image file type: $ext";
}
 
yes, forget the switch stuff, and go with the hash.
 
what's wrong with the 'for' ? - though i normally always go for the hash ;-)

ishnid, what's with this printing headers issue, what's so dangerous about using the print "Content-type: image/gif\n\n"; , I get the variables thing with CGI, but need help understanding what CGI does better/different than simply printing the header by hand.

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
technically there is nothing wrong with it. It's just not very perlish if you ask me.
 
you've lost me Kevin, how is a for statement not perlish?

so to be a real perl head are you saying everything should be in a hash?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
the for() block you have is the same as:

Code:
if ($ext =~ /jpg/) {
   print "Content-type: image/jpeg\n\n";
}
elsif ($ext =~ /gif/) {
   print "Content-type: image/gif\n\n";
}
elsif  ($ext =~ /jpg/){
   print "Content-type: image/jpeg\n\n";
}
else {
   die "Invalid image file type: `$ext'";
}

it's not the for() that is unperlish, it's the conditions you are checking for in a "case/switch" style that is unperlish. If you want to use that method of coding that is perfectly OK. I would use the hash like ishnid showed.
 
I'm not going to row in with an opinion on the "correctness" or otherwise of any particular approach. TIMTOWDTI springs to mind. I do feel that the use of ``for'' to emulate a switch statement is a bit hackish, in that it shoehorns the `for' structure into a situation it was never designed for. The concept of `looping' through a single variable feels a little counter-intuitive to me.
 
They are all valid ways to go about it.
So long as your code is commented, go to town with whichever format works for you.

For tight cases, such as the example shown here, the hash solution looks easiest to implement and maintain.

My personal preference would be to use the switch module over the for() construct, as the 'essence' of what is being done is more obvious when reading the code. Looping over a single scalar makes me go 'huh?'. My 'c' background may make me biased, however.
 
Thanks for the input guys, it did make me go huh? when I saw a for loop against a single scalar and not an array.

allthough I did think it was a cool way to use for to achieve a switch, even if a bit alien.

ishnid - we don't row over anything, we may have heated discussion here on TT at times, but I would never row with you, I respect your help and support over the years far too much for that ;-)

P.S. what does TIMTOWDTI mean?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
TIMTOWTDI - There is more than one way to do it. Its what makes perl so great.

Raklet
 
oic - skin a cat syndrome - lol

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
There's more than one way to do it" is actually Perl's motto (have a look at "perldoc perl" - it's at the bottom). It's also on the cover of the Camel Book.

@1DMF - I didn't mean "row" as-in "argue". It's in the context of rowing a boat with oars. Perhaps it's a colloquial expression that got lost in translation: best interpreted as "I'm not going to barge in with an opinion". Thanks for your kind words though.
 
lol - I take it it's a french term. And I would never consider your posts as
I'm not going to barge in with an opinion
you have been nothing but helpful , informative, patient and a gent, I believe in credit where credit is due.

If it wasn't for you and Rieekan (to mention just a couple - as many other have helped), I'd have no modules, no SQL conectivity, no strict and valid code, no code->presentation separation, no understanding of PERL, infact no website or job!, I'd have been sweeping floors or working on a production line by now, I owe you guys more than you perhaps realise.

You have given me the ability to acheive things I never though possible, the knowledge to progress in my job, expand my experience and make me a better coder in general, for which I can't thank you enough.

Respect to you my friend and my sincere thanks!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Rolling your own headers is the cause of a lot of problems, whereas if you get the module to do it for you, less chance of a typo wrecking your head at 2:30AM.

It's getting quite emotional in here isn't it :-P

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
what would happen if you made a typo using the CGI header method?

I take it CGI has all know MIME type headers in its arsenal?

Plus i wouldn't worry too much, i'm an expert at rolling my own [pimp]

p.s you deserve a star also , as you are included in the role call of honour!

I'm sure that's the only reason you posted, i'm sure it's legendary by now how generous I am with my stars :-P


"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
No, I've had my head wrecked at 2:30 am in the past, and just sharing so less people than possible become afflicted ...

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
print $cgi->header('image/jpeg');

so is this the correct syntax ?

or

print $cgi->header('txt/html);



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top