これまでのPerl5についてのあらすじとこれからのperl-5.18

自己紹介

間違っていたらつっこみください :)

これまでのおさらい

5.10 から 5.16まで、どのような機能が追加されてきたのかご紹介します。

5.10

新しい演算子

// defined-or, ~~ smartmatch

defined-or

sub foo {
    my ($foo) = @_;
    # 引数の値($foo)がなければ、'bar'を入れておこう
    $foo ||= 'bar';
    return $foo;
}

foo();         # $foo is 'bar'
foo('fooooo'); # $foo is 'fooooo'
foo(0);        # $foo is 'bar'?

Perl5における偽である値

前まではこのように書く必要がありました。

sub foo {
    my ($foo) = @_;
    $foo = 'bar' unless defined $foo;
    return $foo;
}

defined-or演算子を使えばスマートに書けるようになります。

sub foo {
    my ($foo) = @_;
    $foo //= 'bar'; # || が傾いて // になった感じ。
    return $foo;
}

smartmatch

die unless $enc eq 'utf8' || $enc eq 'shiftjis' || $enc eq 'euc-jp';

↓それregexp

die unless $enc =~ /^(?:utf8|shiftjis|euc-jp)$/;

↓ それsma

die unless $enc ~~ [qw/utf8 shiftjis euc-jp/];

smartmatchは強力なものの、仕様が難しいので使いにくいという話もあります。

see perldoc perlop

featureプラグマ

say, state, switch

# say
say "Hello, world!";
print "Hello, world!\n"; # だいたいおなじ

# state
sub fetch_image {
    my ($filename) =  @_;
    state $ua = LWP::UserAgent->new();
    my $res = $ua->mirror('http://example.com', $filename);
    die $res->status_line unless $res->is_success;
}

# switch
given () {
    when () {
    }
    default {
    }
}

5.12

5.14

結構すごい

一部のビルトイン関数がリファレンスを受け取れるように

push, unshift, pop, shift, splice, keys, values, each

デリファレンスせずに渡すことができます。

push $arrayref, 'foo';

package Foo {}

{
    package Foo;

    ...
}

package Foo {
    ...
}

s///r 非破壊的な置換

my $foo = 'foobar';
(my $bar = $foo) =~ s/foo/chars/;

my $foo = 'foobar';
my $bar = $foo =~ s/foo/chars/r;

とか

my @foo = qw/foobar barbar bazbar/;
my @bar = map { s/foo/chars/r } @foo; # @fooの中身が破壊されません

5.16

use 5.016; は「5.16で動作するよ」

(今までのような5.16以降で動作する、ではなく)

featureプラグマで有効にできる機能が増えた

unicode_eval evalbytes current_sub array_base fc

詳しくはこちらをご覧ください。 http://akiym.com/slides/20120418-hokkaidopm-casual0-perl-5-16/

おさらい終わり

5.18 (5.17.0-)

これから紹介するのはperl-5.17.7までの変更です。

追加された機能

lexical_subs

レキシカルなサブルーチン

今まで:

{
    my $code = sub {
    };
    $code->();
}

これはダメ:

{
    sub foo {
        ...
    }
    foo();
}

foo();

experimentalな変更なので、いつかのバージョンで取り除かれるかもしれません。

(5.18でもuse feature 'lexical_subs';するとwarningが出るようになっています)

no warnings "experimental::lexical_subs";
use feature 'lexical_subs';

{
    # レキシカルなサブルーチン
    my sub foo {
        ...
    }
    foo();
}
no warnings "experimental::lexical_subs";
use feature 'lexical_subs';

foo();             # パッケージのサブルーチン
state sub foo {
   foo();          # パッケージのサブルーチン
}
foo();             # stateサブルーチン
my $ref = \&foo;   # stateサブルーチンのリファレンス

my sub bar { ... }
bar();             # myサブルーチン

state submy subの違い

our subを使うとこのようなこともできます。

no warnings 'experimental::lexical_subs';
use feature 'lexical_subs';

sub foo { ... } # bar()から呼ばれる

sub bar {
    my sub foo { ... }
    {
        our sub foo;
        foo(); # 外側のfoo()が呼ばれる
    }
}

bar();

5.18の大きな追加機能は以上です。ちょっと少ない感じもしますね。

ここからは細かい話です。

5.17.7

$&, $`, $' を使っても遅くならないように

今まではこれらの変数を使うと遅くなることがありました。

/pフラグをつけるとよいです。

レキシカルな $_ はdeprecatedに

perl-5.10で追加されたレキシカルな $_ はいまいち動作が安定しなく(みんなが)いらないなと思っていました。

5.17.6

one-at-a-timeのかわりにMurmurhash-32を使うことができるようになりました。

その分高速化されるみたいです。

5.17.5

5.17.4

perl-5.18に向けての議論 (まだ)

smartmatch

smartmatchは複雑すぎるし、わりと使う用途が限られているので、もう少し仕様を簡単にしようという話があります。

CPANPLUS

CPANPLUSをコアに入れたことで、CPANPLUSが依存しているたくさんのモジュールがコアに入りました。

CPANPLUSの依存モジュール

File::Fetch
Term::UI
Module::Pluggable
Object::Accessor
Log::Message
Log::Message::Simple
Module::Loaded
Locale::Maketext::Simple
Archive::Extract
Params::Check
Module::Load::Conditional
IPC::Cmd
CPANPLUS
CPANPLUS::Dist::Build

CPANPLUSとか使っている人はもういないし、コアから外してもいいんじゃないかという話があります。

こんなかんじです。perl-5.18.0のリリースが楽しみですね。

さいごに


Perlさん、25周年おめでとうございます。

ありがとうございました。