perl 5.38.0 釋出
作者:gugod 發佈於: ,更新於: #perlperl-5.38.0 變更說明: https://metacpan.org/release/RJBS/perl-5.38.0/changes
摘要:
- 內建的物件導向架構的改善:新增
class,field,method三個定義類別的關鍵字。(實驗性機能。須以use feature 'class';打開。) - 新增對 Unicode 15.0 的支援。
- 新增:讓
PERL_RAND_SEED環境變數為程式開跑時的亂數種子值。相當於去呼叫srand()。 - 讓語法錯誤訊息更加精簡。
- 自動在模組源碼 (內含
package或class的.pm檔案) 最後補上true - 內部用的函式的移除與其文件改善。
- 宣告廢棄:smartmatch (given / when)。名稱空間中的
'分隔符號。
內建的物件導向架構的改善
這應該是這是兩三年來著力最多的部份吧。比起多數提供在 CPAN 上的 OO 框架,perlclass 相對來說很好懂。有三個新的關鍵字與其帶來的新語意,但是幾乎沒有新的語法規則,至少目前沒有。
參考:perlclass 文件。
三個新關鍵字是:class、method、field。class 用來定義類別。method 用來定義 instance method,field 用來宣告 instance variable。
以 class 定義出來的類別會自動以 new 為其 constructor 函式,並且,所有 instance method 體內皆能以 $self 表示目前物件。class 體內的 instance method 的 signature 則不可包含 $self。
而 class 體內的 sub 可用來定義 class method, class 體內的 my 則可用來宣告 private class variable。 class 體內的 our 則可用來宣告 public class variable。
在同一 class 體內以 my、our、field 宣告出來的諸變數是共用同一個名稱空間的。名稱有衝突的話,只有最後一個變數會被留下。
在同一 class 體內以 sub 與 method 宣告出來的各函式也是共用同一個名稱空間的。名稱有衝突的話,只有最後一個函式會被留下。
以 field 宣告出來的變數為 instance variable,只能被用於 instance method 體內。
以 method 定義出來的函式為 instance method,體內可使用 instance variable,同時亦會自動有 $self 可用來代表目前物件。要呼叫其他同一 class 內的 class method 的寫法與普通函式呼叫相同。要呼叫 instance method 時則是需要對 $self 呼叫。
當做範例,以下是一個描述了五段變速電風扇的簡易類別。
use v5.38;
use feature 'class';
use builtin 'true', 'false';
class Fan {
use List::Util qw(min max);
my $__id = 1;
my $RPM_MAX = 600;
my $RPM_MIN = 100;
my $RPM_STEP = 100;
sub vendor { "Cool Company" }
sub speeds { ($RPM_MAX - $RPM_MIN ) / $RPM_STEP }
field $id = $__id++;
field $rpm = 3600;
field $on = false;
method id { $id }
method speed { $rpm / $RPM_STEP }
method turn_on { $on = true }
method turn_off { $on = false }
method faster { $rpm = min($rpm + $RPM_STEP, $RPM_MAX) }
method slower { $rpm = max($rpm - $RPM_STEP, $RPM_MIN) }
method TO_JSON {
+{
# instance method / variable
id => $self->id(),
speed => $self->speed(),
on => $on,
# class method / variable
vendor => vendor(),
speeds => speeds(),
rpm_max => $RPM_MAX,
rpm_min => $RPM_MIN,
}
}
}前述以 sub 定義出來的 class method,其實也可以被當成是 instance method 來呼叫。例如 Fan 類別的 vendor ,有兩種呼叫方式:
my $fan = Fan->new;
say $fan->vendor(); # (1)
say Fan->vendor(); # (2)(1) 與 (2) 兩處對應到的函式是同一個。
以 class 所附的 new 函式所做出來物件,字串形式上會有個 OBJECT 字樣:
my $fan = Fan->new;
say "$fan";
#=> Fan=OBJECT(0x19477b0);如果是以常見的 blessed HashRef 做法 (即:bless {}, 'Fan') 所造出來的物件,其字串形式是這樣:
Fan=HASH(0x1b3a5e8)由此可窺知在 perl 內部多了一種以 OBJECT 為表記的值。
自動在模組源碼最後補上 true
以往都要在 .pm 檔案最後補個 1;,然後還得向人說明這行看似無作用的程式碼的用途。以後在開頭加上 use v5.38; 後就不必在檔尾補 1 了。
# Foo.pm
use v5.38;
package Foo {
sub foo() { "Bar" }
}附帶一提,就算在最後在 Foo.pm 最後故意加上 0;,也不會讓 use Foo; 失敗。