この記事は, 「はてなエンジニア Advent Calendar 2023」の10日目の記事です.
9日目の記事は, id:cockscomb さんの「SwiftにおけるTyped throwsの現在」でした.
そして「Perl Advent Calendar 2023」の10日目の記事でもあります.
9日目の記事は, @bayashi_net さんの「Module::Setupをgo moduleのセットアップにも使っている話」でした.
先日, Hatena Tech Book Vol.2に「Perlの未定義動作110連発」という記事を書きました.
この記事は, 以前このブログに書いた「Perlの未定義動作100連発」の加筆修正版です.
「Perlの未定義動作100連発」や「Perlの未定義動作110連発」で紹介した未定義動作は, そのほとんどが「まあ, そんな書き方はしないだろう...?」というものですが, その中で比較的よく見かけるのが「my + 後置if」です.
注意: (my $x if ... のような) 条件構造やループ構造で修飾された my state,our 文の振る舞いは 未定義 です。 my 変数の値は undef かも知れませんし、以前に代入された値かも 知れませんし、その他の如何なる値の可能性もあります。 この値に依存してはいけません。 perl の将来のバージョンでは現在のバージョンとは何か違うかも知れません。 ここには厄介なものがいます。
use strict; use warnings; use DDP; my $num1 = 123 if 1; my $num2 = 345 if 0; p $num1; p $num2;
こういう実装は, レビューで指摘してもらう前に気付きたいものです. 何か良い手はあるかな? と思ったらPerl::CriticにPerl::Critic::Policy::Variables::ProhibitConditionalDeclarationsというポリシーがあるので, これで検知することができます. 先のコードであれば, 次のように警告してくれます:
Variable declared in conditional statement at line 5, column 1. Declare variables outside of the condition. (Severity: 5) Variable declared in conditional statement at line 6, column 1. Declare variables outside of the condition. (Severity: 5)
ちなみに, Perl::LintにもPerl::Lint::Policy::Variables::ProhibitConditionalDeclarationsというポリシーがあるので, 同様に検知することができます.
余談
ところで, ここまで何気なく「後置if」と呼んでいました. 実は, Perlのドキュメントの日本語訳であるところのperldoc.jpを確認してみると, 「後置if」というワードは存在しません. この書き方は, perlsynの「文修飾子」で紹介されているので, むしろ「if文修飾子」と呼ぶべきなのかもしれません.
...となると, 「後置if」という呼び方の由来(?)はどこにあるんだろう, ということが気になってきますね. これについては, 機会があれば調べてみたいと思います.
「はてなエンジニア Advent Calendar 2023」の明日の担当は id:ne-sachirou さん*1です. よろしくお願いします.
*1:12/11が誕生日とのこと, おめでとうございます!!!