15

那里有很多,因为 Perl 是一种非常含糖的语言,但任何语言中最常用的语句是 if 语句和设置值的组合。我想我已经找到了很多,但仍有一些差距。最终,目标是不必多次编写变量名:

这是我到目前为止所拥有的:

$r ||= $s;          # $r = $s unless ($r);
$r //= $s;          # $r = $s unless (defined $r);
$r &&= $s;          # $r = $s if ($r);
$r = $c ? $s : $t;  # if ($c) { $r = $s } else { $r = $t }
$c ? $r : $s = $t;  # if ($c) { $r = $t } else { $s = $t }
$r = $s || $t;      # if ($s) { $r = $s } else { $r = $t }
$r = $s && $t;      # if ($s) { $r = $t } else { $r = $s = undef, 0, untrue, etc. }
$c and return $r;   # return $r if ($c);
$c or  return $r;   # return $r unless ($c);
$c and $r = $s;     # $r = $s if ($c);
@$r{qw(a b c d)}    # ($r->{a}, $r->{b}, $r->{c}, $r->{d})

有人也有一篇关于“秘密操作员”的非常有趣的文章,如下所示:

my @part = (
    'http://example.net/app',
    ( 'admin'  ) x!! $is_admin_link,
    ( $subsite ) x!! defined $subsite,
    $mode,
    ( $id      ) x!! defined $id,
    ( $submode ) x!! defined $submode,
);

但是,我发现列表中缺少的是:

$r <= $s;                 # read as "$r = min($r, $s);" except with short-circuiting
$r = $s if (defined $s);  # what's the opposite of //?
$r and return $r          # can that be done without repeating $r?

还有什么值得补充的吗?还有哪些其他条件集变量可用于减少代码?还缺少什么?

4

5 回答 5

8

使用低优先级andor关键字可以更清楚地写出您问题中的这些结构:

$c and return $r;    # return $r if ($c);
$c or return $r;     # return $r unless ($c);
$c and $r = $s;      # $r = $s if ($c);

andand的好处or在于它与语句修饰符控制词不同,and并且or可以链接到复合表达式中。

语法糖的另一个有用工具是使用for/foreach循环作为单个值的主题化器。考虑以下:

$var = $new_value if defined $new_value;

对比

defined and $var = $_ for $new_value;

或类似的东西:

$foo = "[$foo]";
$bar = "[$bar]";

$_ = "[$_]" for $foo, $bar;

map函数也可以以这种方式使用,并且具有您可以使用的返回值。

于 2011-10-17T19:42:23.933 回答
6

还有左侧的三元运算符:

$cond ? $var1 : $var2 = "the value";

相当于:

if ($cond) {
    $var1 = "the value";
} else {
    $var2 = "the value";
}
于 2011-10-18T08:07:05.433 回答
3

$r = $r < $s ? $r : $s;

    $r = $s if $r > $s;

或者

    use List::Util qw( min );

    $r = min($r, $s);

或者:

    sub min_inplace {
       my $min_ref = \shift;
       for (@_) { $$min_ref = $_ if $$min_ref > $_; }
    }

    min_inplace($r, $s);

$r = $s if (defined $s);

    $r = $s // $r;

$r = $t; $r = $s if (defined $s);

    $r = $s // $t;

$r = !$s ? $s : $t;

    $r = $s && $t;
于 2011-10-17T17:48:58.083 回答
1

Perl 中最需要的特性之一是switch语句。这最终出现在 Perl 5.10 中。我只是使用文档中的示例:

use feature qw(say switch);  #My preference
#use feature ":5.10";        #This does both "say" and "switch"

[...]

given($foo) {
    when (undef) {
        say '$foo is undefined';
    }
    when ("foo") {
        say '$foo is the string "foo"';
    }
    when ([1,3,5,7,9]) {
        say '$foo is an odd digit';
        continue; # Fall through
    }
    when ($_ < 100) {
        say '$foo is numerically less than 100';
    }
    when (\&complicated_check) {
        say 'a complicated check for $foo is true';
    }
    default {
        die q(I don't know what to do with $foo);
    }
}

为什么 o' 为什么他们使用given/when而不是switch/case就像你在大多数语言中发现的那样,对我来说是个谜。而且,为什么如果语句是given/ when,你会在use featuresas中指定它switch吗?

唉,做出这些决定的人比我更高,所以我什至没有权利质疑这些杰出人物。


我避免使用更奇特的东西,并坚持使用最容易理解的语法。想象一下,必须检查您的代码并发现添加功能的错误的人,这对那个人来说更容易理解:

$r &&= $s;

或者

if ($r) {
    $r = $s;
}

而且,也许我可能会意识到我的真​​正意思是:

if (not defined $r) {
    $r = $s;
}

而且,在这种情况下,我什至可以说:

$r = $s if not defined $r;

尽管我通常不喜欢后置 if 语句,因为人们if在浏览代码时往往会错过该部分。

Perl 是在运行时编译的,编译器相当高效。因此,即使它写起来更酷,$r &&= $s而且它为你赢得了更多的极客积分,而且打字更少,但它的执行速度并没有任何提高。花在代码上的最大时间是在维护它,所以我宁愿跳过花哨的东西并追求可读性。

顺便说一句,当我想到语法糖时,我会想到添加到语言中以提高可读性的东西。一个很好的例子是->运算符:

${${${$employee_ref}[0]}{phone}}[0];

对比

$employee_ref->[0]->{phone}->[0];

当然,如果您将数据作为对列表的引用存储到对列表的散列的引用,那么使用面向对象的编码可能会更好。

于 2011-10-17T17:15:10.780 回答
0

还有:

$hash{$key||'foo'} = 1;  # if($key) { $hash{$key} = 1 } else { $hash{'foo'} = 1 }
于 2011-10-19T22:47:03.590 回答