perl 5.38.0 釋出

作者:   發佈於: ,更新於:   #perl

perl-5.38.0 變更說明: https://metacpan.org/release/RJBS/perl-5.38.0/changes

摘要:

內建的物件導向架構的改善

這應該是這是兩三年來著力最多的部份吧。比起多數提供在 CPAN 上的 OO 框架,perlclass 相對來說很好懂。有三個新的關鍵字與其帶來的新語意,但是幾乎沒有新的語法規則,至少目前沒有。

參考:perlclass 文件。

三個新關鍵字是:classmethodfieldclass 用來定義類別。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 體內以 myourfield 宣告出來的諸變數是共用同一個名稱空間的。名稱有衝突的話,只有最後一個變數會被留下。

在同一 class 體內以 submethod 宣告出來的各函式也是共用同一個名稱空間的。名稱有衝突的話,只有最後一個函式會被留下。

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