daw*_*awg 17 syntax perl conditional
要刷新,C和Perl中的条件运算符是:
(test) ? (if test was true) : (if test was false)
如果与左值一起使用,您可以使用一个动作进行分配和测试:
my $x=  $n==0 ? "n is 0" : "n is not 0";
我正在阅读伊戈尔·奥斯特罗夫斯基(Igor Ostrovsky)的博客,以一种简洁的方式来表达基于C语言的多语句if语句,并且意识到这在Perl中确实是一种"巧妙的方式".
例如:(编辑:使用Jonathan Leffler更易读的形式......)
# ternary conditional form of if / elsif construct:
my $s=
      $n == 0     ? "$n ain't squawt"
    : $n == 1     ? "$n is not a lot"
    : $n < 100    ? "$n is more than 1..."
    : $n < 1000   ? "$n is in triple digits"
    :               "Wow! $n is thousands!" ;  #default
其中读取的内容比许多人在Perl中写的更容易:(编辑:my $t=do{ if };在rafi的回答中使用了cjm更优雅的形式)
# 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 < 100)  { "$n is more than 1..."   }
    elsif ($n < 1000) { "$n is in triple digits" }
    else              {  "Wow! $n is thousands!" }
};
这里有任何问题或缺点吗?为什么我不以这种方式编写扩展条件形式而不是使用if(something) { this } elsif(something) { that }?
条件运算符具有正确的关联性和低优先级.所以:
a ? b : c ? d : e ? f : g
被解释为:
a ? b : (c ? d : (e ? f : g))
如果您的测试使用的是少数优先级较低的运算符之一,我想您可能需要括号?:.你也可以把格子放在带支撑的形状中.  
我确实知道被弃用的use Switch或关于Perl 5.10的given/when结构,我不是在寻找使用它们的建议.
这些是我的问题:
你有没有看到Perl中使用的这种语法?**我没有,它不在perlop或perlsyn作为切换的替代.
以这种方式使用条件/三元运算符是否存在潜在的语法问题或"陷阱"?
意见:你对它更具可读性/可理解性吗?它与Idiomatic Perl一致吗?
--------编辑 -
我接受了Jonathan Leffler的回答,因为他向我指出了Perl最佳实践.关于表格三元的相关部分是6.17 .这让我可以进一步调查使用情况.(如果你是Google Perl Tabular Ternaries,你可以看到其他评论.)
康威的两个例子是:
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";
}
VS:
           # 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"
           ;
我的结论是:
?:对于我而言,Conway的示例比if/elsif表单更具可读性和简单性,但我可以看到表单如何难以理解.
如果您有Perl 5.13.1,请将my $t=do { given { when } };其用作rafi已完成的任务.我认为given/when现在是最好的成语,除非表格三元格式更适合您的特定情况.
如果您通常使用Perl 5.10+ given/when而不是Switch或者如果您需要某种类型的案例类型切换.
较旧的Perl,这是一个很好的形式,用于简单的替代或作为案例陈述的替代.它比Switch我想的更好.
从右到左的关联性意味着从下到上评估表单.请记住,使用时......
raf*_*afl 19
我在perl中看过这个习惯用法.由于三元运算符? :是一个运算符,所以它是记录在内的perlop,而不是perlsyn.
在我看来,这是一种惯用的Perl,但Perl的主要目的似乎是避免缺乏适当的switch声明,而不是写大型的if/else卡片.但是,这在几年前已经在perl 5.10.0中修复.这些天我没有看到很多理由没有写上面的内容,这似乎比(ab)使用三元组更具可读性:
given ($n) {
    when (0)         { $t = "$_ ain't squawt"        }
    when (1)         { $t = "$_ is not a lot"        }
    when ($_ < 100)  { $t = "$_ is more than 1..."   }
    when ($_ < 1000) { $t = "$_ is in triple digits" }
    default          { $t = "Wow! $_ is thousands!"  }
}
或者,从perl 5.13.1开始,即使如下:
my $t = do {
    given ($n) {
        when (0)         { "$_ ain't squawt"        }
        when (1)         { "$_ is not a lot"        }
        when ($_ < 100)  { "$_ is more than 1..."   }
        when ($_ < 1000) { "$_ is in triple digits" }
        default          {  "Wow! $_ is thousands!" }
    }
};
另一个替代方案是这样的,适用于所有perl版本:
my @cases = (
    [sub { $_ == 0 },   sub { "$_ ain't squawt"        }],
    [sub { $_ == 1 },   sub { "$_ is not a lot"        }],
    [sub { $_ < 100 },  sub { "$_ is more than 1..."   }],
    [sub { $_ < 1000 }, sub { "$_ is in triple digits" }],
    [sub { 1 },         sub { "Wow! $_ is thousands!"  }],
);
for my $case (@cases) {
    local $_ = $n;
    next unless $case->[0]->();
    $t = $case->[1]->();
    last;
}
虽然这可以避免使用巨大的if/elsif/else级数,并且不需要最近的perls的功能,但这个简单的例子可能不值得努力.但是,我非常看到这样的方法在很多条件下都有用,并且需要支持旧的perls.
(另请注意,您的初始示例不会处理$ n小于零或根本不是数字.)
来自cjm的注释:您也可以在Perl 5的所有版本中执行此操作:
my $t = do {
    if    ($n == 0)   { "$n ain't squawt"        }
    elsif ($n == 1)   { "$n is not a lot"        }
    elsif ($n < 100)  { "$n is more than 1..."   }
    elsif ($n < 1000) { "$n is in triple digits" }
    else              {  "Wow! $n is thousands!" }
};
Jon*_*ler 15
显示条件运算符的布局很难阅读.这更像是我记得Perl Best Practices推荐的内容:
my $s = $n == 0   ? "$n ain't squawt"
      : $n == 1   ? "$n is not a lot"
      : $n < 100  ? "$n is more than 1..."
      : $n < 1000 ? "$n is in triple digits"
      :             "Wow! $n is thousands!";  # default...
有时候用符号表示更紧凑的符号也更好if:
  if    ($n == 0)   { $t = "$n ain't squawt";        }
  elsif ($n == 1)   { $t = "$n is not a lot";        }
  elsif ($n < 100)  { $t = "$n is more than 1...";   }
  elsif ($n < 1000) { $t = "$n is in triple digits"; }
  else              { $t = "Wow! $n is thousands!" ; }  
这两种重新格式化都强调了代码各个部分的相似性,使其更易于阅读和理解.
我已经看到了相当多的链式条件,有时使用它,并且总是讨厌它.这很方便但很难看,除非你走极端去格式化并简化插页式广告.
一旦你遇到它们并且意识到这是一个成语,它们就不那么难以理解了.但是,更容易理解正确的switch语句.也有可能错误地放置冒号并以难以现场的方式弄乱一切.