この記事は、Perl Advent Calendar 2025 24日目の記事です。 23日目は@shogo82148で「Perlクラスのレキシカルメソッドを試してみる」でした。
背景
ネタが尽きてきたので、引き続きperldeltaから頑張ってネタを探すシリーズをやっていこうと思います。
Perl 5.42 では警告にもいくつかの変更がありました。 そのうちよく引っかかりそうなものについて見ていきましょう。
否定演算子の優先順位に関する警告
たとえば以下のようなコードを考えてみましょう。
use v5.42;
my $x = 5;
my $y = 10;
if (!$x < $y) { # バグ! (!$x) < $y を解釈される
print "$x is not less than $y\n";
} else {
print "$x is less than $y\n";
}
実行すると「5 is not less than 10」という誤った結果を返します:
Possible precedence problem between ! and numeric lt (<) at ./test.pl line 5.
5 is not less than 10
なぜかと言うと !$x < $y が (!$x) < $y と解釈されるためです。
Perl 5.42からはこのようなケースに対して警告を出すようになりました。
Possible precedence problem between ! and numeric lt (<) at ./test.pl line 5.
もっとも簡単な修正方法は、カッコで優先順位を明示することでしょう。
use v5.42;
my $x = 5;
my $y = 10;
if (!($x < $y)) {
print "$x is not less than $y\n";
} else {
print "$x is less than $y\n";
}
これで警告も出なくなりますし、意図した通りの挙動になります。
万が一 (!$x) < $y と解釈されるのが正しい!という場合も、カッコで優先順位を明示することで、警告を無効化できます。
use v5.42;
my $x = 5;
my $y = 10;
if ((!$x) < $y) { ... }
(あんまり有用なケースが思いつきませんが・・・)
算術比較演算子 (<) 以外にも以下のような演算子で警告がでるそうです。
!$x < $y # parsed as: (!$x) < $y
!$x eq $y # parsed as: (!$x) eq $y
!$x =~ /regex/ # parsed as: (!$x) =~ /regex/
!$obj isa Some::Class # parsed as: (!$obj) isa Some::Class
見慣れない警告が出ても慌てないよう、しっかり覚えておきましょう。
voidコンテキストにおける連鎖比較
Perlには元々無意味な文を警告してくれる機能があります。
たとえば以下のコードで、$x だけの行はどこにも代入していないので無意味です。
use v5.42;
my $x = 5;
$x; # どこにも代入していないので無意味
実行してみると、このような行を警告してくれます。
Useless use of private variable in void context at ./unused.pl line 4.
Perl 5.42からは比較連鎖も警告の対象となります。
use v5.42;
my $x = 5;
1 < $x < 10;
実行結果:
Useless use of comparison chaining in void context at ./unused.pl line 4.
まとめ
Perl 5.42から有効になった警告についてまとめてみました。 演算子の優先順位に関するミスと、演算結果を無意味に捨てているケースが警告されるようになりました。
エディターにbscan/PerlNavigator をインストールしていれば、コードを書いている途中でも警告してくれて便利です。 こちらもぜひ試してみてください。
明日25日は@__papix__で「YAPC::Fukuoka 2025お疲れ様でした。」です。
🐰✨
新しい警告のお話を添えて
Perl 5.42の知恵を束ねて
括弧で明らかにする優先度
バグ防止の道を照らして
ウサギが祝う、コンテンツの輝き!by CodeRabbit