Perl 中可以使用哪种语法糖来减少左/右值运算符与 if 语句的代码?

发布于 2024-12-10 12:32:01 字数 1400 浏览 0 评论 0原文

那里有很多语句,因为 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?

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

There's a bunch out there, as Perl is a pretty sugary language, but the most used statements in any language is the combination of if statements and setting values. I think I've found many of them, but there's still a few gaps. Ultimately, the goal would be to not have to write a variable name more than once:

Here's what I have so far:

$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})

Somebody also had a really interesting article on a "secret operator", shown here:

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

However, what I've found to be missing from the list is:

$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?

Is there anything else worth adding? What other conditional set variables are available to reduce the code? What else is missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

神仙妹妹 2024-12-17 12:32:01

您的问题中的这些结构可以使用低优先级 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);

and 和 < code>or 与语句修饰符控制字不同,andor 可以链接成复合表达式。

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

$var = $new_value if defined $new_value;

vs

defined and $var = $_ for $new_value;

或类似的东西:

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

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

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

These structures from your question could be written a little bit more clearly using the low precedence and and or keywords:

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

The nice thing about and and or is that unlike the statement modifier control words, and and or can be chained into compound expressions.

Another useful tool for syntactic sugar is using the for/foreach loop as a topicalizer over a single value. Consider the following:

$var = $new_value if defined $new_value;

vs

defined and $var = $_ for $new_value;

or things like:

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

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

the map function can also be used in this manner, and has a return value you can use.

2024-12-17 12:32:01

还有左侧三元运算符:

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

相当于:

if ($cond) {
    $var1 = "the value";
} else {
    $var2 = "the value";
}

There's also the left hand side ternary operator:

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

is equivalent to:

if ($cond) {
    $var1 = "the value";
} else {
    $var2 = "the value";
}
治碍 2024-12-17 12:32:01

<代码>$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 (已定义 $s);:

    $r = $s // $r;

$r = $t; $r = $s if (已定义$s);:

    $r = $s // $t;

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

    $r = $s && $t;

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

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

or

    use List::Util qw( min );

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

or:

    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;
安人多梦 2024-12-17 12:32:01

Perl 中最需要的功能之一是 switch 语句< /a>.这最终出现在 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);
    }
}

为什么他们选择 given/when 而不是 switch/像您在大多数语言中发现的那样,对我来说是一个谜。而且,为什么如果语句是given/when,那么您是否在use features中将其指定为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];

vs.

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

当然,如果您将数据存储为列表到哈希到列表的引用,那么您最好使用面向对象的编码。

One of the biggest called for features in Perl was the switch statement. This finally appeared in Perl 5.10. I'm just using the example from the documentation:

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);
    }
}

Why o' why did they go with given/when and not switch/case like you find in most languages is a mystery to me. And, why if the statement is given/when, do you specify it in use features as switch?

Alas, the people who made these decisions are at a higher plane than I am, so I have no right to even question these luminaries.


I avoid the more exotic stuff, and stick with the easiest to understand syntax. Imagine the person who has to go through your code and find a bug of add a feature, which would be easier for that person to understand:

$r &&= $s;

or

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

And, maybe I might realize that I really meant:

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

And, in this case, I might even say:

$r = $s if not defined $r;

Although I don't usually like post-fixed if statements because people tend to miss the if part when glancing through the code.

Perl is compiled at runtime, and the compiler is fairly efficient. So, even though it's way cooler to write $r &&= $s and it earns it earns you more geek points and is less to type, it doesn't execute any faster. The biggest amount of time spent on code is on maintaining it, so I'd rather skip the fancy stuff and go for readability.

By the way, when I think of syntactic sugar, I think of things added to the language to improve readability. A great example is the -> operator:

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

vs.

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

Of course, if you're storing data as a reference to a list to a hash to a list, you are probably better off using object oriented coding.

爱的那么颓废 2024-12-17 12:32:01

还有:

$hash{$key||'foo'} = 1;  # if($key) { $hash{$key} = 1 } else { $hash{'foo'} = 1 }

There's also:

$hash{$key||'foo'} = 1;  # if($key) { $hash{$key} = 1 } else { $hash{'foo'} = 1 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文