Perl 5.36.0 帶來的新機能
作者:gugod 發佈於: #perl在 2022 年 5 月釋出的 Perl 5.36.0 版中有不少舊的機能被徹底移除,但也多了不少新的機能。其中幾項令我注目的有:
- subroutine signature
- true, false, is_bool 及 builtin (實驗組)
- 一次抓出多個值的 for 迴圈 (實驗組)
subroutine signature
subroutine signature 在各語言中的意義都略有不同,但粗略地來說就是讓函式的參數列表成爲函式名稱的一部分。不過在 Perl 5.36.0 中尚沒有這麼先進,僅是把 @_
這個代表參數列表的變數給藏了起來而已:
5.36.0 前的寫法:得多寫一行把 @_
中各參數內容給拷貝出來:
sub foo {
my ($p, $q) = @_;
...
}
自 5.36.0 起,可改寫成如下。把參數直接列在函式名後面。在語法上,省去了使用 @_
的一步。
sub foo ($p, $q) {
...
}
這個語法自 5.20 版開始就被加入實驗組,幾番修改,現在總算是正式成爲核心語法的一部分了。
與此同時,如果在帶了參數列表的函式本文內又使用了 @_
,就會讓 perl 發出警告。例如:
use v5.36;
sub plus ($p, $q) {
return $p + $_[1];
}
say plus(10, 1);
輸出:
Use of @_ in array element with signatured subroutine is experimental at /tmp/x.pl line 4.
11
可看到 $_[1]
還是等於 $q
,也還是可以用。但在執行時則會有一行警告訊息跑出來。
此外,還有個附帶的好處:在函式呼叫處,如果參數的個數與宣告處的參數個數不同,則會產生執行時期的錯誤,並且就地停止。比方說我們故意丟三個參數給 plus
:
use v5.36;
sub plus ($p, $q) {
return $p + $q;
}
say "begin";
say plus(10, 1, 42);
say "end";
輸出:
begin
Too many arguments for subroutine 'main::plus' (got 3; expected 2) at /tmp/x.pl line 8.
可看到這程式輸出只到 "begin"
爲止,沒有包含 plus
傳回值,也沒有包含 "end"
。
其實我覺得最好是讓它在編譯時期就中止,不過目前這樣也還算不錯。只是在重構程式時要確保沒有少改任何一處,以免到部署上線之後才發現錯誤連連。
true, false, is_bool 及 builtin
一直以來 Perl 語言中都沒有對應到 true 與 false 這兩個值,現在有了。在程式中明確寫下來的 true
與 false
,在函式呼叫傳值的過程中,都會被好好保留著。但,這兩個關鍵字尚不是直接就建在語言內,而是要自名爲 builtin
的這個個新核心模組引入。除了新關鍵字之外,所有測試用運算子都會回傳 true
或 false
,而要明確判別 true
/false
與其他值,則必須用 is_bool
。
use v5.36;
use builtin qw( true false is_bool );
my $p = (1 == 1);
say is_bool( $p ) ? "bool" : "not bool"; #=> "bool"
除了滿足新世代的「寫作習慣」之外,有特定值來代表 true
/ false
的好處就是能在將各變數轉換成 JSON 時,能夠清楚區分出 1
、"1"
與 true
的不同,。
一次抓出多個值的 for 迴圈
這次在 for
迴圈的語法上加入了一次抓出多個值的新規則。讓人可以利用這種特性,使陣列內容兩兩一組或三三一組,做出簡單的資料結構。簡單的範例如下:
use v5.36;
for my ($x, $y, $z) (1..11) {
say "$x $y $z";
}
輸出:
for my (...) is experimental at /tmp/x.pl line 4.
1 2 3
4 5 6
7 8 9
Use of uninitialized value in concatenation (.) or string at /tmp/x.pl line 5.
10 11
可看到,在串列長度與迭代變數的個數不正好是倍數關係時,於最後一輪中,就會有幾個變數變成 undef
。這設計還算合理。
感想
這次的新版出現了很多變更,稍微試用之後都覺得各設計還算合理。但似乎也有人覺得新語法的加入,漸漸地讓 Perl 語言失去了一些一致性,各語句之間變得越來越不像。不過多數變更都還是放在實驗組中的,起目的就是在於讓大家試用,找出癥結與痛點,加以改善,或是整組丟掉。
新的 builtin
核心模組的出現似乎是個不錯的方向,可把一些常用的,或不得不用的函式內部化,如果能逐漸充實到使人無需利用 CPAN 模組就能完成大部分簡單任務,那其實會是個很好的結果。