Greytree

TamWiki

For a mouse who is a packrat

Technology » To Switch Or Not To Switch
discussion on when to use the switch control structure and alternatives

Summary:this is what goes at the top of the site

(redirected from Main.ToSwitchOrNotToSwitch)

When it comes to choosing when to use the switch control structure, vs. a chain of if-elseif-else statements, there are many opinions. Many find chains of if-elseif-else statements to be crude and ugly. That said, sometimes there is no alternative. Fortunately, in PHP and Perl, there usually are alternative. The switch control structure is remarkably flexible in what it can do.

Let's compare

A typical cascading if-elseif-else structure:

  1. if ($result == 'image/jpeg') {
  2.     $ext = 'jpg';
  3. } elseif ($result == "image/gif") {
  4.     $ext = "gif";
  5. } elseif ($result == "image/png") {
  6.     $ext = "png";
  7. } else {
  8.     $ext = "dat";
  9. }

Whereas, if we were to use a switch statement, we'd get:

  1. switch ($result) {
  2.     case 'image/jpeg': $ext = "jpg"; break;
  3.     case 'image/gif': $ext = "gif"; break;     
  4.     case 'image/png': $ext = "png"; break;     
  5.     default: $ext = "dat"; break;
  6.   }

Which seems more elegant and readable to you? I tend to vote for the switch implementation over the cascading if-elseif-else structure.

Another alternative

While the above example shows the difference plainly between if-elseif-else and switch statements, there is actually a better alternative in this case: a lookup table.

Somewhere in your source, create a lookup table:

  1. $mapmimetoextension = (
  2.     'image/jpeg' => 'jpg',
  3.     'image/gif' => 'gif',
  4.     'image/png' => 'png',
  5.     # ... and so on
  6. );

Then, to determine the extension given the mimetype, you could simply do:

  1. $ext = isset($mapmimetoextension[$mimetype] ? $mapmimetoextension[$mimetype] : 'dat';

Which seems a lot cheaper than either the cascading if-elseif-else or the switch. Given the desire to keep code modular, it would also likely save on a procedure call.

That's fine for PHP, what about Perl?

Perl Switch Constructs

Unlike some other programming languages, Perl has no official switch or case statement. That's because Perl doesn't need one, having many ways to do the same thing. A bare block is particularly convenient for doing case structures (multiway switches). Here's one:

  1. SWITCH: {
  2.     if (/^abc/) { $abc = 1; last SWITCH; }
  3.     if (/^def/) { $def = 1; last SWITCH; }
  4.     if (/^xyz/) { $xyz = 1; last SWITCH; }
  5.     $nothing = 1;
  6. }

and here's another:

  1. SWITCH: {
  2.     /^abc/      && do { $abc = 1; last SWITCH; };
  3.     /^def/      && do { $def = 1; last SWITCH; };
  4.     /^xyz/      && do { $xyz = 1; last SWITCH; };
  5.     $nothing = 1;
  6. }

Both of these constructs operate on matching the $_ variable. I prefer the second form (no nasty if's going on there. Note that the both forms can be much more convoluted there. There is no need to necessarily restrict one's self to making comparisons with the $_ variable. Basically any test can be made in the case portion of the switch construct.

What makes this work is the last SWITCH; statement. It basically quits the switch when it is executed.


Tags: Categories: Articles

Recent Changes | Printable View | Page History | Edit Page
Page last modified on April 17, 2012, at 08:59 PM by ImportText?