title: Should I use Perl's conditional ? : operator as a switch / case statement or instead of if elsif?
body: <p>Perl has a <a href="http://perldoc.perl.org/perlop.html#Conditional-Operator" rel="nofollow noreferrer">conditional</a> operator that is the same a <a href="http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Conditional-Expressions" rel="nofollow noreferrer">C's conditional operator</a>. </p>
  
  <p>To refresh, the conditional operator in C and in Perl is:</p>
  
  <pre><code>(test) ? (if test was true) : (if test was false)
  </code></pre>
  
  <p>and if used with an lvalue you can assign and test with one action:</p>
  
  <pre><code>my $x=  $n==0 ? "n is 0" : "n is not 0";
  </code></pre>
  
  <p>I was reading Igor Ostrovsky's blog on <a href="http://igoro.com/archive/a-neat-way-to-express-multi-clause-if-statements-in-c-based-languages/" rel="nofollow noreferrer">A neat way to express multi-clause if statements in C-based languages</a> and realized this is indeed a "neat way" in Perl as well. </p>
  
  <p>For example: (edit: used Jonathan Leffler's more readable form...)</p>
  
  <pre><code># ternary conditional form of if / elsif construct:
  my $s=
        $n == 0     ? "$n ain't squawt"
      : $n == 1     ? "$n is not a lot"
      : $n &lt; 100    ? "$n is more than 1..."
      : $n &lt; 1000   ? "$n is in triple digits"
      :               "Wow! $n is thousands!" ;  #default
  </code></pre>
  
  <p>Which reads a LOT easier than what many would write in Perl:
  (edit: used cjm's more elegant <code>my $t=do{ if };</code> form in rafi's answer)</p>
  
  <pre><code># Perl form, not using Switch or given / when
  my $t = do {
      if    ($n == 0)   { "$n ain't squawt"        }
      elsif ($n == 1)   { "$n is not a lot"        }
      elsif ($n &lt; 100)  { "$n is more than 1..."   }
      elsif ($n &lt; 1000) { "$n is in triple digits" }
      else              {  "Wow! $n is thousands!" }
  };
  </code></pre>
  
  <p>Are there any gotchas or downside here? Why would I not write an extended conditional form in this manner rather than use <code>if(something) { this } elsif(something) { that }</code>? </p>
  
  <p>The conditional operator has <a href="http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity" rel="nofollow noreferrer">right associativity and low precedence</a>. So:</p>
  
  <pre><code>a ? b : c ? d : e ? f : g
  </code></pre>
  
  <p>is interpreted as:</p>
  
  <pre><code>a ? b : (c ? d : (e ? f : g))
  </code></pre>
  
  <p>I suppose you might need parenthesis if your tests used one of the few operator of lower precedence than <code>?:</code>. You could also put blocks in the form with braces I think.  </p>
  
  <p>I do know about the deprecated <code>use Switch</code> or about Perl 5.10's <code>given/when</code> constructs, and I am not looking for a suggestion to use those.</p>
  
  <p>These are my questions: </p>
  
  <ul>
  <li><p>Have you seen this syntax used in Perl?** I have not, and it is not in <code>perlop</code> or <code>perlsyn</code> as an alternate to switch.</p></li>
  <li><p>Are there potential syntax problems or 'gotchas' with using a conditional / ternary operator in this way?    </p></li>
  <li><p>Opinion: Is it more readable / understandable to you? Is it consistent with Idiomatic Perl?</p></li>
  </ul>
  
  <p><strong>-------- Edit --</strong></p>
  
  <p>I accepted Jonathan Leffler's answer because he pointed me to <a href="https://rads.stackoverflow.com/amzn/click/com/0596001738" rel="nofollow noreferrer" rel="nofollow noreferrer">Perl Best Practices</a>. The relevant section is 6.17 on <em>Tabular Ternaries.</em> This allowed me to investigate the use further. (If you Google Perl Tabular Ternaries, you can see other comments.)</p>
  
  <p>Conway's two examples are:</p>
  
  <pre><code>my $salute;
  if ($name eq $EMPTY_STR) {
      $salute = 'Dear Customer';
  }
  elsif ($name =~ m/\A ((?:Sir|Dame) \s+ \S+)/xms) {
      $salute = "Dear $1";
  }
  
  elsif ($name =~ m/([^\n]*), \s+ Ph[.]?D \z/xms) {
      $sa1ute = "Dear Dr $1";
  }
  else {
      $salute = "Dear $name";
  }
  </code></pre>
  
  <p>VS:</p>
  
  <pre><code>           # Name format...                            # Salutation...
  my $salute = $name eq $EMPTY_STR                       ? 'Dear Customer'
             : $name =~ m/ \A((?:Sir|Dame) \s+ \S+) /xms ? "Dear $1"
             : $name =~ m/ (.*), \s+ Ph[.]?D \z     /xms ? "Dear Dr $1"
             :                                             "Dear $name"
             ;
  </code></pre>
  
  <p>My conclusions are:  </p>
  
  <ul>
  <li><p>Conway's <code>?:</code> example is more readable and simpler to me than the <code>if/elsif</code> form, but I could see how the form could get hard to understand. </p></li>
  <li><p>If you have Perl 5.13.1, use <code>my $t=do { given { when } };</code> as an assignment as <a href="https://stackoverflow.com/questions/3898836/should-i-use-perls-conditional-operator-as-a-switch-case-statement-or-ins/3898866#3898866">rafi has done.</a> I think <code>given/when</code> is the best idiom now, unless the tabular ternary format is better for your particular case. </p></li>
  <li><p>If you have Perl 5.10+ use <code>given/when</code> in general instead of <code>Switch</code> or if you need some sort of case type switch. </p></li>
  <li><p>Older Perl's, this is a fine form for <em>simple</em> alternatives or as an alternate to a case statement. It is better than using <code>Switch</code> I think. </p></li>
  <li><p>The right to left associativity means the form is evaluated bottom to top. Remember that when using...</p></li>
  </ul>