Perl v5.40 新特性有哪些?

本文最初发表在 The Weekly Challenge


Perl,最灵活、最强大的编程语言,仍在不断发展。随着将 Corinna 添加到核心 Perl 中,我期待着每个版本的发布,以带来新功能。在 2024年6月9日,我们发布了最新的公共版本 Perl v5.40。在这个版本中,进行了重大的改进。您可以亲自查看 主要特色

在这篇文章中,我想分享我的个人喜好。

1. 新的 __CLASS__ 关键字
2. 字段变量的 :reader 属性
3. -M 命令行选项中允许有空格
4. 新的 ^^ 逻辑异或运算符
5. try/catch 功能不再实验性
6. for 迭代多个值不再实验性

1. 新的 __CLASS__ 关键字


你还记得我们那位老朋友 __PACKAGE__ 吗?嗯,它是一个特殊令牌,返回它所在包的名称。通常,你会在 Moose 类中找到这个 __PACKAGE__->meta->make_immutable

__PACKAGE__ 类似,我们现在有一个新的特殊令牌 __CLASS__ 用于新的核心面向对象。在大多数情况下,它的行为与 __PACKAGE__ 相同。话虽如此,当你处理 子类 时,它就特别闪亮了。


use v5.40;
use experimental 'class';

class Example1 {
    field $x = __CLASS__->default_x;
    field $y = __CLASS__->default_y;

    sub default_x { 10 }
    sub default_y { 20 }
    method sum { return $x + $y }
}

class Example2 :isa(Example1) {

    sub default_x { 1 }
    sub default_y { 2 }
}

say Example1->new->sum;  # 30
say Example2->new->sum;  # 3

2. 字段变量的 :reader 属性


Perl v5.38 中引入新的面向对象后,这是创建类的方式。


use v5.38;
use experimental 'class';

class Employee {
    field $name :param;
    field $age  :param;

    method name    { return $name }
    method get_age { return $age  }
}

my $emp = Employee->new(name => "Joe", age => 40);
say $emp->name;      # Joe
say $emp->get_age;   # 40


如果你注意到,方法 name()get_age() 只是一个通用的 getter 方法。

幸运的是,在最新版本中,可以使用 :reader 实现同样的效果,而无需显式定义 getter 方法,如下所示。

我必须承认,这比以前干净得多。


use v5.40;
use experimental 'class';

class Employee {
    field $name :param :reader;
    field $age  :param :reader(get_age);
}

my $emp = Employee->new(name => "Joe", age => 40);
say $emp->name;      # Joe
say $emp->get_age;   # 40


有两种变体,一种是提供常规的 getter,另一种可以提供自己的方法名称。

你可能想知道,“setter 呢?”

嗯,我希望在下一个版本中我们也能得到它。


3. 在 -M 命令行选项中允许有空格


Perl v5.40 之前,这是使用 -M 开关的方式。


$ p538 -MList::Util=sum -E 'say sum(1, 2, 3, 4)'
10


然而,如果你在较早的 Perl 中强制添加空格,你会得到错误 Missing argument to -M,如下所示


$ p538 -M List::Util=sum -E 'say sum(1, 2, 3, 4)'
Missing argument to -M


Perl v5.40 的发布中,你不再得到错误。


$ p540 -M List::Util=sum -E 'say sum(1, 2, 3, 4)'
10

4. 新的 ^^ 逻辑异或运算符


Perl v5.40 之前,我们有 3 个低优先级逻辑运算符 andorxor。同时,我们还有 2 个中等优先级逻辑运算符 &&||

Perl 的早期版本中,这是使用低优先级 xor 运算符的方式。


use v5.38;

my $x = 1;
my $y = 0;

($x xor $y) and say 'Either $x or $y is true but not both.';


通过添加新的中等优先级异或运算符 ^^,可以实现同样的效果,如下所示


use v5.40;

my $x = 1;
my $y = 0;

$x ^^ $y and say 'Either $x or $y is true but not both.';

5. try/catch 功能不再实验性


我们都知道 try/catch 被添加到核心 Perl v5.34 中作为实验性功能。


use v5.34;
use experimental 'try';

try {
    1/0;
} catch ($e) {
    say "try/catch exception: $e";
}


即使在 Perl v5.36 中,它仍然是实验性的。


use v5.36;
use experimental 'try';

try {
    1/0;
} catch ($e) {
    say "try/catch exception: $e";
}


然而,在 Perl v5.40 中,它不再实验性了。 万岁!!!


use v5.40;

try {
    1/0;
} catch ($e) {
    say "try/catch exception: $e";
}

6. for 同时迭代多个值的特性不再实验性


你还记得在 Perl v5.36 的核心中添加了同时迭代多个值的实验性功能吗?


use v5.36;
use experimental 'for_list';

for my ($p, $q) (1,2,3,4) {
    say $p, $q;
}


Perl v5.40 中不再实验性。


use v5.40;

for my ($p, $q) (1,2,3,4) {
    say $p, $q;
}

为了展示实时结果,请参见下文


$ p540 -E 'for my ($p, $q) (@ARGV) { say $p, $q; }' 1 2 3 4
12
34

$ p540 -E 'for my ($p, $q) (@ARGV) { say $p, $q; }' 1 2 3 4 5
12
34
5

$ p540 -E 'for my ($p, $q) (@ARGV) { say $p, $q; }' 1 2 3 4 5 6
12
34
56

到目前为止,我仅仅触及了表面。也许在下一篇文章中,我会尝试探索更多增强。

标签

穆罕默德·萨吉德·安瓦尔

穆罕默德是2022年白骆驼奖获得者,也是CPAN 贡献者。他喜欢提交pull请求并在Perl会议上发言。他运营每周挑战。他也是Perl Weekly通讯的合编者。更多关于他的信息,请访问他的网站

浏览他们的文章

反馈

这篇文章有什么问题吗?请通过在GitHub上打开问题或pull请求来帮助我们。