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;
失敗。