(1)はこちら、(2)はこちらから。
関数に型制約を導入する
関数の引数と戻り値に対し型制約を適用することで、期待する値を限定でき堅牢さが高まります。
Function::Parameters──関数の引数の型制約
Type::Tiny
にはType::Params
という引数チェック用ライブラリが同梱されていますが、本稿ではFunction::Parameters
2.001003を解説します。Function::Parameters
はパフォーマンスこそ若干Type::Params
に劣るものの[1]、後述するコード検査が行える利点があります。
Function::Parametersの使い方
Function::Parameters
は、fun
もしくはmethod
キーワードで関数定義を行います。関数の引数にStr $msg
と書けば、$msg
がStr
の型制約を満たすかを判定します。指定する型制約は、値が期待どおりか判定するcheck
メソッドと、エラーメッセージを返すget_message
メソッドさえダックタイピングされていればよく、Type::Tiny
はもちろん、Moose(あるいはMouse)::Meta::TypeConstraint
も利用できます。
名前付き引数は:$name
のように変数名にコロンを付け、初期値は$name=DEFAULT
のように指定できます。
Function::Parametersでコード検査を行う
関数の引数が多すぎると誤用が起きることは容易に想像できます。Function::Parameters
では定義した関数から引数の数を含むメタ情報を抽出できるので、自動テストにこの検査を組込み、関数の引数の数が多すぎるコードを未然に防げます。
引数の個数の検査以外にも、型情報を用い、アプリケーションの事情を加味したコード検査もできます。堅牢生を高めるために、こういった実行時以外の検査を行えることは大きな利点です。
Function::Return──関数の戻り値の型制約
拙作のFunction::Return
0.02で、関数の処理結果も型制約でチェックできます。次のコードでは、関数の戻り値がStr
かチェックしています。
Function::Parameters
と組み合わせて使うこともでき、引数と戻り値が期待する型が一目でわかり、可読性の向上も望めます。
Function::Returnでメタ情報を取得する
Function::Parameters
と同様に、Function::Return
も戻り値に関するメタ情報を取得でき、コード検査などに利用できます。現在のバージョンでは、$info->types
で指定した型制約を取り出せます。
関数呼び出しのコンテキストの固定
Perlは関数の呼び出し方に応じて、関数の挙動を変更できます。具体的には、wantarray
の値に応じ、リストコンテキスト、スカラコンテキスト、ボイドコンテキストの分岐を行えます。おもしろいしくみで、慣れればコードを省力的に書くことを助けてくれます。
しかし、アプリケーションの開発においては、アプリケーションロジックやチームメンバーは流動的です。チームの皆が慣れた状況は作りにくいため、アプリケーション開発ではコンテキストに応じた挙動変更は避けたほうがよいと考えます。Function::Return
は、明示されている型制約を優先し、内部的に関数の呼び出しのコンテキストを固定し、この問題を回避しています。たとえば、次のように複数の型制約を指定した場合、リストコンテキストで呼び出すことを強要します。
Perlに慣れている人からすると逆に不自然かもしれませんが、Num
, Str
で返却する約束を優先するようになっています。
Function::Returnのオプション設定
Function::Return
はReturn
という関数の属性をエクスポートしますが、自分の好きに設定したい場合もあります。たとえば、次のコードはOut
という名前に変更しています。
以下はパフォーマンスを優先したい場合のオプションです。
戻り値の型チェックは、関数の処理が間違っていないかどうか確認するには便利ですが、本番環境ではパフォーマンスの都合で不要かもしれません。Function::Return
のオプションにno_check
を指定することで、型チェックをしないように変更できます。
まとめ
本稿では、始めに堅牢な開発を行うための予防策として、プラグマで構文チェックを厳しくする方法やPerl::Critic
を用いた静的検査を紹介しました。次に、Type::Tiny
で型制約を導入する方法を示しました。そして最後に、Function::Parameters
とFunction::Return
で関数の入出力を動的に型チェックし、さらに関数のメタ情報でコード検査する方法を紹介しました。
Perlの柔軟さを活かして、堅牢さを足すこともできると思っていただけたら幸いです。
さて、次回の執筆者は上川慶さんで、テーマは「Cを用いたPerl拡張入門」です。お楽しみに。
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現!
- 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう
- 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、NFT