本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは小林謙太さんで、
堅牢な開発とは、
本稿は、
Perlに約束を入れて、異常を予防する
異常が起きてから対処するより、
checkオプションで構文チェックを行う
Perlで書いたプログラムの構文が正しいかを確認するには、perl -c foo.
のように-c
オプションを付けてプログラムを実行します。perldoc perlrun
に書いてあるとおり、BEGIN
、UNITCHECK
、CHECK
ブロックのコードを実行します。たとえば次のコードでperl -c
した場合、BEGIN
ブロックの中が実行されてHELLO
と標準出力して、pprint
の記述が構文エラーであると指摘します。こういったブロックにアプリケーションロジックを記述することは、
一方、
プラグマを利用し、より厳しい構文チェックを行う
Perlインタプリタにヒントを与えるためのしくみとして、$^{WARNING_
やヒントハッシュと呼ばれる$^H
、%^H
といった組込みの変数があり、
このコードでは、BEGIN
ブロックで抽選した値に応じ、
まずは標準プラグマのstrict
プラグマとwarnings
プラグマを紹介します。これらのプラグマは本連載第7回
strictプラグマで、安全でない構文を制限する
strict
プラグマを使わなかった場合、$var
の値を"var"
という文字列だけで参照できます。柔軟ですが、strict
プラグマを利用し、
strict
プラグマがほかに制限できる構文について、perldoc strict
を参照してください。
warinigsプラグマで、警告ではなく致命的なエラーを選択する
warnings
プラグマも、strict
プラグマと同様に意図せぬ挙動になりがちなPerlの構文を制限します。たとえば、
しかし、warnings
プラグマは、FATAL
オプションにどの警告カテゴリを昇格させるかを指定します。
このコードでは、FATAL
オプションに警告カテゴリのnumeric
を指定しています。これにより、FATAL
オプションにall
を指定することで、
表1に、perldoc perldiag
を参照してください。
警告のカテゴリ | 内容 |
---|---|
numeric | 文字列が、 |
experimental | signaturesといったPerlの実験的な機能の使用 |
deprecated | Perlで非推奨となった機能の使用 |
once | 一意な変数名がtypo |
redefine | サブルーチンを再定義したとき |
exec | system() やexec() などで、 |
recursion | 無限再帰の可能性がある |
newline | ファイル名に改行文字が含まれる可能性がある |
portable | 32ビットで表現できる数値を超えている |
stricturesプラグマで、バランスの良い約束を入れる
構文チェックを厳しくするためにwarnings FATAL =>'all'
を行うのも手ですが、recursion
は無限再帰の可能性を示しているだけで、strictures
です。strictures2.
を用いて説明します。
上記は、
strictures 2
を指定して、PERL_
環境変数も有効にすると、
new Foo
といった間接オブジェクト記法を禁止し、$hash{1,2}
といったキーに配列を利用した呼び出しを禁止し、<FH>
といったBareword
によるファイルハンドルの扱いを禁止します。
構文チェックを一部外す方法
未然に問題に気付くために構文チェックは厳しいほうがよいと思いますが、
Perl::Criticで静的検査を行う
次に、Perl::Critic
1.
なお、
perlcriticを使ってみる
Perl::Critic
に同封されるperlcritic
と呼ばれるコマンドラインツールを使ってみましょう。実際の用途としては、
次のコードは、strict
が有効になっていないため警告が出ています。
strict
プラグマを有効にして、
先ほどの警告にあった(Severity: 5)
は静的検査の厳しさを指し、3
と指定した場合の例です。
この指摘の意味はそれぞれ、1;
で終わっていない、warnings
プラグマを利用していない、
.perlcriticrcで、静的検査のルールを指定する
Perl::Critic
では、~/.perlcriticrc
ファイルに静的検査の設定を記述します。基本的な設定例は次のとおりです。
Subroutines::ProhibitSubroutinePrototypes
の先頭に-を添え、
静的検査チェックのルール一覧を確認する
適用可能な静的検査のルール一覧はperlcritic --list
で取得でき、.perlcriticrc
を適用したルール一覧はperlcritic --list-enabled
で取得できます。各ルールの概要をつかむのであれば、Perl::Critic::PolicySummary
を読むことをお勧めします。以下、
InputOutput::ProhibitTwoArgOpen
open $fh, "< $file"
と書くより、open $fh, '<', $file
と書くModules::RequireFilenameMatchesPackage
package Foo::Bar
というパッケージであれば、Bar.
というファイル名である必要があるpm Subroutines::ProhibitExplicitReturnUndef
- 失敗時の返却は、
return undef
と書くより、return
と書く Subroutines::ProhibitReturnSort
- スカラコンテキストで
sort
が呼び出されたときの挙動は定まっていないため禁止 Variables::ProhibitConditionalDeclarations
my $foo = $bar if $baz;
という変数宣言を禁止BuiltinFunctions::ProhibitStringyEval
eval "my $foo; bar($foo);
と書くより、eval { my $foo;bar($foo) }
と書く
ここまでに、Perl::Critic
を用いて未然に異常を防ぐ方法を紹介しました。アプリケーションによらない汎用的な解決手段ですので、
<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT