The three significant features in Perl 5.14

perl 5.14.0がリリースされた。Ubuntuなどでは、perlbrew経由でインストールするといくつかテストが失敗するようなので--forceオプションを使わないとインストールできない。

# 念のため-DDEUGGINGもつける。threadは好みで。
$ perlbrew --force install perl-5.14.0 -DDEBUGGING -Duseithreads

Task::Plackなどの主要モジュール群ではCoro以外はいまのところ問題なくインストールできている。
さて、このバージョンは数多くの機能がが追加されているが、特に重要な機能が三つある。このエントリではその機能を紹介する。

The package block syntax

package宣言が他の言語のクラス宣言に近い形で書けるよう拡張された。特に、以下のような小さなクラスが分かりやすくに書けるようになる。

#!perl -w
use 5.14.0;
package Point {
    use Mouse;

    has [qw(x y)] => (
        is       => 'rw',
        isa      => 'Num',
        required => 1,
    );

    __PACKAGE__->meta->make_immutable();
}

say Point->new( x => 10, y => 20 )->dump();
__END__

なお、モジュールにする場合は依然として最後の1;は必要である*1
ところでuseで5.12以上のバージョンを指定すると自動的にuse strictが掛かることも併せて覚えておきたい。

See also package block syntax in perldelta.

Non-destructive substitution

非破壊的な置換s///rが追加された。5.14より前のバージョンでは、ある配列要素に対して非破壊的な置換を行うには以下のようにしなければならなかった。

my @newvalues = map {
        my $tmp = $_;
        $tmp =~ s/foo/bar/g;
        $tmp;
    } @values;

これが5.14からは以下のように一行ですむようになる。

my @newvalues = map { s/foo/bar/gr } @values;

See also Non-destructive substitution in perldelta.

Array and hash container functions accept references

配列やハッシュのための関数群がリファレンスを受け付けるようになった。これはこれは以前大きく取り上げたことがあるが、コンテナの扱いが非常に簡単になる革新的な機能である。

#!perl -w
use 5.14.0;
package MyStack {
    use Mouse;

    has _container => (
        is  => 'ro',
        isa => 'ArrayRef',

        default => sub { [] },
    );

    sub push {
        my($self, @values) = @_;
        push $self->_container, @values;
        return $self;
    }
    sub pop {
        my($self, @values) = @_;
        return pop $self->_container;
    }
    sub top {
        my($self) = @_;
        return $self->_container->[-1];
    }
}

my $stack = MyStack->new();
$stack->push(30);
$stack->push(20);
say $stack->dump();
__END__

push/popの際に@{}デリファレンスする必要がなくなっている。個人的には、これが5.14の新機能の中でもっとも使いたいものだ。
See also Array and hash container functions accept references in perldelta.

その他

Perl 5.14は他にも数多くの変更がある。大きなものではないが非互換の変更もいくつかある。したがってperldeltaには軽く目を通しておきたい。

*1:しかし、Mouse/Mooseを使うなら__PACKAGE__->meta->make_immutable()が真を返すのでであまり意識する必要はない。