本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーはcharsbarこと石垣憲一さんで、テーマは
<前回
今後実装されそうな機能
実際にPerl本体に入った機能と、プロトタイピングに使われたCPANモジュールの機能やToDoメモを比較すると、これから実装されていくであろう機能が予想できます。同様に、Paul Evans氏がSyntax::Keyword
やSyntax::Operator
といった名前を冠してリリースしているほかの実験的なモジュールも、今後取り込みの対象となっていくことが予想されます。ここではその一部を紹介します。
複数のcatch
ブロック ──より柔軟なエラー処理
Syntax::Keyword::Try
モジュールにはバージョン0.catch
ブロックを持つ構文が実験的な機能として存在しています。ここではPerl 5.isa
演算子を利用して、try
ブロックの中で発生したエラーが既知のMyException
クラスのものか、それ以外のエラーなのかを判定しています。
use v5.36;
use Exception::Class 'MyException';
use Syntax::Keyword::Try qw(
try
:experimental
);
try {
do_something()
or die MyException->throw(
error => 'exception',
);
}
catch ($e isa MyException) { ... }
catch ($e) { ... }
さまざまな演算子
Perl 5.
その反省もあって、Perl本体のほうでは演算子もキーワードと同じようにプロトタイピングできるようにするしくみの実験が続いていたのですが、Perl 5.
Syntax::Operator::Equ
モジュール
従来のコードでは、未定義値が入るかもしれない変数を適切に比較するには次のように書く必要がありました。
if ((defined $x && defined $y && $x eq $y) ||
(!defined $x && !defined $y)) { ... }
if ((defined $x && defined $y && $x == $y) ||
(!defined $x && !defined $y)) { ... }
Syntax::Operator::Equ
モジュールは、従来の等価演算子の動作に加えて両方とも未定義の場合も真を返す演算子を提供します。
use v5.37;
use Syntax::Operator::Equ;
if ($x equ $y) { ... }
if ($i === $j) { ... }
Syntax::Operator::ExistsOr
モジュール
Perl 5.//
演算子が導入されましたが、Syntax::Operator::ExistsOr
モジュールはハッシュにキーが存在していなければ右辺の値を返す\\
演算子を提供します。
use v5.37;
use Syntax::Operator::ExistsOr;
my %hash = (foo => 'bar');
say $hash{baz} \\ 'quuz'; # quuz
Syntax::Operator::Divides
モジュール
Syntax::Operator::Divides
モジュールは、倍数かどうかを判定する%%
演算子を提供します。
use v5.37;
use Syntax::Operator::Divides;
for (1 .. 100) {
if ($_ %% 15) { say "FizzBuzz"; }
elsif ($_ %% 5) { say "Fizz"; }
elsif ($_ %% 3) { say "Buzz"; }
else { say $_; }
}
match
~case
文 ──条件分岐の再実装
複数の条件分岐を1つにまとめるgiven
キーワード、when
キーワードもスマートマッチ演算子とともに廃止が決まり、削除が予定されています。その代替として、Syntax::Keyword::Match
モジュールの実験成果も取り込まれていくことでしょう。match
文は、従来のgiven
文と異なり比較に使う演算子を明示的に指定するのが特徴です。
use v5.37;
use Syntax::Keyword::Match;
use Syntax::Operator::Equ;
match ($str : equ) {
case (undef) {
say "not defined"
}
case ("") {
say "defined but empty"
}
default {
say "non-empty"
}
}
クラスの各種機能
Perl 5.perlclass
ドキュメントには、優先的な実装が期待されるToDoがいくつか記載されています。
ロール ──再利用可能なメソッド群
Object::Pad
モジュールには、再利用可能なメソッドをまとめたロールを定義するrole
キーワードが用意されています。ロールをクラスに組み込むにはclass
文の:does
属性を利用します。継承の順序に応じてメソッドが上書きされていく多重継承と異なり、ロールの組込み時にはメソッドの衝突が確認されるので、うっかりメソッドが上書きされることはありません。
use Object::Pad;
role Greet {
method say_hi {
say "Hi, I'm " . $self->name;
}
}
class Person :does(Greet) {
...
# method say_hi { say "Hi, I'm $name"; }
}
Object::Pad
モジュールの:does
属性は必要に応じて複数個設定できます。1つの:does
属性の中に複数個のロールを設定することはできません。
field
文のアクセサ属性 ──メソッドの自動生成
Object::Pad
モジュールには、field
文に:reader
や:writer
、:accessor
という属性を追加することでアクセサメソッドを自動的に生成するしくみが用意されています。
use Object::Pad;
class Person {
field $name :param :reader;
field $age :param :accessor;
# method name { $name }
# method age {
# @_ ? $age = shift : $age;
# }
}
メタプログラミング
クラスの内部を覗いたりクラスの機能を拡張したりするのに必要なメタプログラミングの機能も課題に挙がっています。メタプログラミング機能は、Object::Pad
モジュールのバージョン0.
use v5.36;
use Object::Pad qw(:experimental);
use Object::Pad::MetaFunctions qw(metaclass);
class Author :isa(Person) :does(Greet) { ... }
my $author = Author->new(...);
my $meta = metaclass($author);
say $_->name for $meta->superclasses;
say $_->name for $meta->all_roles;
say $_->name for $meta->direct_methods;
メタプログラミング機能については、Perlの機能変更の提案を管理しているGitHubリポジトリで、正式な機能提案に向けての議論が進んでいます。このリポジトリも最近のPerlの開発体制の変化とともに導入されたもので、もとはRFCsdefer
キーワードのほか、Perl 5.builtin
名前空間や、Perl 5.export_
キーワードなどの議論もまとめられています。
周辺ツールの対応
クラスは新しいしくみですので、Perl本体だけでなく、周辺ツールの対応も必要になります。
たとえば、class
文によるオブジェクトの内部構造は従来のbless
文によるオブジェクトとは異なるため、本稿執筆時点ではData::Dumper
モジュールで内部を見ようとしたり、Storable
モジュールで複製を作成しようとしたりすると、エラーが発生します。
また、モジュールのバージョンを抽出するツールなどもclass
文には未対応のものが多いため、そのままではCPANへのアップロードなどの際に問題が発生します。この問題については次の例のように従来のpackage
文と$VERSION
変数を利用したバージョン指定を併記しておくことで回避できますが、いずれはツールチェイン側の対応が入るはずです。
use v5.37;
use experimental qw(class);
package Author;
our $VERSION = '0.01';
class Author 0.01 { ... }
まとめ
今回紹介した機能はいずれもまだ実験が続いているため、正式な機能に昇格するまでには時間がかかりそうですが、プロトタイピングは済んでいるため大きく変化することはないでしょう。新たにPerlのコードを書くことがあったらぜひ積極的に使ってみてください。これらの機能がそろった暁には、Perlのメジャーバージョンが
さて、次回の執筆者は宮川達彦さんで、テーマは