Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

Perl5.40の変更点

こんにちは、エンジニアの id:mp0liiu です。

かなり遅くなってしまいましたが、今年も6/10にPerlの最新安定バージョンである5.40がリリースされたので新機能や変更点についてまとめます。

安定化した実験的機能

try-catch 構文

5.34 で追加された try-catch 構文が安定化して use feature 'try' もしくは use v5.40 で有効にできるようになりました。

use v5.40;
 
try {
    die 'Some error occurred.';
    say 'Success';
}
catch ($e) {
    say 'Failure';
}

finally ブロックに関してはまだ実験的機能なので注意してください。
finally ブロックを使用した際に発生する警告を抑制するには no warnings qw( experimental::try ); が必要です。

forループの繰り返しごとに複数の要素を参照する構文

5.36で追加された、for文の括弧内にレキシカル変数を列挙することで複数の要素に対して反復処理を行う構文が実験的でなくなりました。

my %hash = (
    a => 1,
    b => 2,
);
 
for my ($key, $value) (%hash) {
    say "$key => $value";
}
a => 1
b => 2

builtin モジュール

5.36で追加された、新しい組み込み関数を提供しかつ組み込み関数を扱う新しい仕組みである builtin コアモジュールが安定化しました。
builtin で提供される関数の中にはまだ実験的な関数もあります。詳しくは builtin モジュールのドキュメントを参照していただきたいですが、5.40 では 5.36 で追加されたほとんどの関数が安定化しています。

5.40 で安定化した関数をまとめて使いたい場合は use builtin ':5.40' するかもしくは use v5.40 します。
以前の記事でも解説していますが、安定化した関数の中でもリストの各要素の順番と各要素のペアのリストを返す関数 indexed、真値と偽値を返す true と false、blessed などリファレンス判定系の関数、ceil、floor あたりの関数は使う頻度が高いと思うので積極的に利用していきたいです。

実験的な関数を使う場合は以前同様警告が発生するため、抑制したい場合は no warnings 'experimental::builtin'; する必要があります。

ちなみにこれによりforループの繰り返しごとに複数の要素を参照する構文と indexed 関数を組み合わせて配列のindexと要素の列挙が楽に書けるようになっています。

use v5.40;
 
my @array = qw( red blue green );
for my ($index, $value) (indexed @array) {
    say "$index => $value";
}
0 => red
1 => blue
2 => green

その他の変更

class 構文のフィールド変数に reader 属性を指定可能に

5.38 に実験的機能として追加された class 構文のフィールド変数に reader 属性を指定可能になりました。
これは getter メソッドを自動で生成する機能です。(Moose でいうところの is => 'ro' なアクセサ)

field $name :reader;

field $name;
method name () { return $name; }

と同等です。

use v5.40;
use experimental 'class';

class People {
  field $name :param :reader;
}
 
say People->new(name => 'John')->name; # John

みたいな使い方になると思います。

__CLASS__ キーワードが追加

こちらも class 構文の話で、method文, ADJUSTブロック、フィールド変数の初期化式の中で呼び出し元のクラス名を返すキーワードです。
やっていることは ref($class) と同じで、スーパークラスから呼び出された場合はスーパークラス名を返し、サブクラスから呼び出された場合はサブクラス名を返すようになっています。

use v5.40;
use experimental 'class';
 
class Parent {
  field $num :reader = __CLASS__->DEFAULT_NUM;
  sub DEFAULT_NUM { 10 }
}
 
class Child :isa(Parent) {
  sub DEFAULT_NUM { 20 }
}
 
say Parent->new->num; # 10
say Child->new->num; # 20

優先度の高い排他的論理和演算子、 ^^ が追加

Perlの論理演算子は評価優先度の高い &&, || と優先度の低い and, or とがありますが、今まで排他的論理和演算子は優先度の低い xor 演算子しかありませんでした。
5.40からは優先度の高い排他的論理和演算子、 ^^ が追加され利用できるようになります。

builtin に関数 inf と nan, load_module が追加

builtin モジュールに新しい実験的関数が追加されました。
inf は無限を、nan は非数を返す関数です。inf は今までオーバーフローする浮動小数点演算を行って得ていた値を、nan は inf 同士の計算で得ていた値を返してくれるので状況によっては便利になりそうです。

load_module は引数にモジュール名を渡すことで実行時にモジュールロードを行う関数です。コアモジュールである Module::Loadload 関数を builtin に持ってきた形になるかと思います。

5.40までに追加された 関数 は use v5.40;use builtin ':5.40' で使用することができますが、5.40 で新たに追加された builtin に関数の使用は use builtin '関数名' が必要です。 また使用した際に発生する警告を抑制するには no warnings 'experimental::builtin' が必要です。

Test2::Suite がコアに追加

Test2を用いて作られたテストツール群 Test2::Suite がコアに同梱されるようになりました。
要は Test2::V0 でテストが書けるようになります。Test2::V0 は追加のテストモジュールをインストールしなくても現代的なテストが書けるテストモジュールで、複雑なデータ構造のテストを簡単にかけたり、RSpec風のテストがかけたり、テスト結果が見やすくなったりと良いことがたくさんあるので積極的に利用していきたいです。

goto による外部スコープから内部スコープへのジャンプが廃止予定に

goto で外部スコープから内部スコープにジャンプすることが Perl5.42 で廃止されることになりました。
例えば以下のようなコードは動かなくなります。

{
  LABEL:
  say "smoething";
}
goto LABEL;

goto を使ったコードを書いてる人はほとんどいないと思うのであまり影響はないかと思いますが、古かったり複雑なループ処理をしているコードだと使われている箇所もあるかもしれないので一度確認した方が良さそうです。
5.40 では上記のようなコードがあると警告が発生するようになっています。

まとめ

今回は5.38のときほどの大きな変更はありませんでしたが、重要な実験的機能が安定化したり細かな改善をしたりと、確実に進化し続けています。
次回以降の安定バージョンでも名前付き引数や文字列中で式展開ができる構文などが入る気配があり楽しみです。

この記事では書けなかったこともあるので詳しいことが気になった方は公式ドキュメントもぜひ読んで見てください。