最近のPerlの機能
リファレンスの引き方がわかったところで、
Perlの安定バージョンについて
perlの安定版はバージョン番号X.
perlの公式安定版として一番新しいのは5.
以降では最近のPerlの機能を、
5.10からの機能
まずは5.
featureプラグマ──新機能を使うおまじない
最初はあっと驚く機能ではないけれど重要な機能の紹介です。新しい機能は、
これはプログラム冒頭でuse feature qw(say switch)
のように書く
たとえばuse feature ':5.
と書けば5.use 5.
やuse v5.
と書いても同じです。ただし、use v5.
とすると、use feature ':5.
に加えてuse strict;
相当にもなります。筆者はuse strict効果を狙いつつ、use v5.
を好んで使っています。
use feature 'say';
とすると、
say関数──改行付きで出力
print関数は\nを自分で付けないと改行してくれませんが、say $string;はprint $string, "\n";
と同じです。ちょっと出力したいときに改行をいちいち書かなくてよいのは、
say関数自体はPerlの文法に何の影響も与えていないので、
defined-or演算子──undefとそれ以外を区別
defined-or演算子はオペランドを2つ$A // $B
のように書きます。名前のとおり、defined $A
が真でなければ$Bを評価して返します。似たような演算子としてor 演算子$A || $B
がありますが、
次のように使います。
my $bar = $foo // 1;
$fooがundefの場合、
また、
$baz->{foo} //= 'hello, world!';
$baz->{foo}
がundef ならば'hello, world!'
を代入する、
この演算子は非常に重要です。Perlにおいては空の文字列の''も、
sub title {
my ($self) = @_;
$self->{_title} ||= $self->retrieve_title_from_db;
}
この例では、
defined-or演算子を使わずにor演算子を使っているため、$self->retrieve_
が空文字列の場合、$self->retrieve_
が評価されることになってしまいます。データベースアクセスが発生する場合は特に望ましくない挙動です。defined-or演算子を使えば、$self->{_title}
がundefの場合のみ$self->retrieve_
が評価されることになり安心です。
5.
my $bar = defined $foo ? $foo : 1;
$baz->{foo} = defined $baz->{foo} ? $baz->{foo} : 1;
sub title {
my ($self) = @_;
$self->{_title} =
defined $self->{_title} ? $self->{_title} :
$self->retrieve_title_from_db;
}
自己代入の場合などは特に冗長になって書きにくく、
この演算子を使うためだけでも、
正規表現のnamed-capture──キャプチャの参照が楽に
Perlの正規表現では、
次の例のようにただの括弧の代わりに(?という書き方をすることで、
$+{識別子}
や$-{識別子}
という書き方で参照できるようになります
、%-
というハッシュに値が入り、$+{識別子}
でハッシュの値を取得するという意味です)。
my $string = 'http://example.com/foo/bar';
$string =~ m{^http://(?<host>[^\s/]+)(?<path>/\S+)$};
say $+{host};
say $+{path};
特に便利なのは、$+{rgb}
にマッチした文字列が入ります。
$string =~ m{
(?<rgb>\#[0-9a-f]{6}) |
(?<rgb>\#[0-9a-f]{3})
}xi;
say $+{rgb};
同じ名前で複数の場所がキャプチャされた場合、$+{rgb}
には最後にマッチした内容が入ります。全部欲しいケースでは、$-{識別子}
という特殊な変数を使います。$-{識別子}
には配列リファレンスですべての値が入っています。
my $string = "aaa bbb ccc";
$string =~ m{(?<chars>...) (?<chars>...)};
$-{chars}; #=> ['aaa', 'bbb']
正規表現が複雑になるほど、
スマートマッチ演算子──いい感じに真偽を返す
スマートマッチ演算子は、$A ~~ $B
として使います。スマート
簡単な例を挙げます。
warn 'a' ~~ [qw/a b c/];
#=> 1
warn 'x' ~~ [qw/a b c/];
#=> Warning: something's wrong
スマートマッチ演算子は右辺が配列リファレンスだと、
今のところこの演算子は速度が非常に遅いのと、
挙動はオペランドの型によって変わります。全部のパターンについてはperldoc perlsyn
に書いてあります。
switch文──条件を並列に書く
switch文は、
次の例のように、$foo
が"foo"
か"bar"
か、default
)
given ($foo) {
when ("foo") { ... }
when ("bar") { ... }
default { ... }
}
また、
given ($foo) {
$foo ~~ [0..9] と同じ
when ([0..9]) { ... }
$foo ~~ [10..19] と同じ
when ([10..19]) { ... }
default { ... }
}
しかし、
given (0) {
when (2 == 2) { say 1 } #=> 1
}
不思議な挙動に感じられるかもしれませんが、
switch文も細かい挙動は複雑ですが、perldoc perlsyn
に書いてありますので、
state関数──新しいスコープの導入
state関数は、state $i = 0;
と、
例を見ればすぐわかります。次のコードのcounterサブルーチンでstate $i = 0;
と宣言していますが、
sub counter {
state $i = 0;
$i++;
}
say counter(); #=> 0
say counter(); #=> 1
say counter(); #=> 2
state相当のことは5.
{ my $i = 0;
sub counter {
$i++;
}
}
state関数はこれを簡潔に書けるようにしたものです。
encoding::warnings──文字化けするコードを検出
Perl本体の機能ではありませんが、
encoding::warningsによって、
現代においてはこの暗黙的なアップグレードを狙ってコードを書くことはありえないと思いますので、use encoding::warnings 'FATAL'
として、