Perl は明確なコンテキスト依存性を持つ言語です:式の結果は、その結果がどのように使用されるかによって異なります。歴史的にこの特性は言語を非常に柔軟にしましたが、経験豊富な開発者でさえ、スカラコンテキストとリストコンテキストの動作の特性を考慮しないと誤解を招くことがあります。
この問題は Perl の初期バージョンから存在し、同じ操作が配列または単一の値を返す可能性があると仮定されました — 例えば、localtime 関数は状況に応じてリストまたは文字列を返すことができます。
問題 は、コンテキストの誤った処理が予期しないエラーにつながることです:たとえば、余分な要素、空の結果、または論理式の奇妙な動作です。
解決策 は、関数や式がどのコンテキストで呼び出されているかを常に明示的に理解し、サブルーチン内で組み込み関数 wantarray を使用して、コンテキストの暗黙の混在を防ぐことです。
コード例:
sub may_return { return wantarray ? (1, 2, 3) : "scalar result"; } my @arr = may_return(); # (1,2,3) を返す my $val = may_return(); # "scalar result" を返す
主な特長:
wantarray を使用します。関数内で式が void コンテキストで使用されているかどうかを特定できますか?
回答:いいえ、スカラかリストかだけです。Perl 5 にはサブルーチン内での void コンテキストを判断する関数はなく、wantarray はこの場合に undef を返しますが、別の挙動のためです。
コード例:
sub example { return wantarray ? (1,2) : wantarray ? undef : "scalar"; # 不正確 }
関数はコンテキストに応じて異なるデータ型を返すことができますか?
回答:はい、完全に許可されており、しばしば使用されます。
演算子の動作(例:shift、pop)はコンテキストに依存しますか?
回答:はい。例えば、shift が関数内で呼び出されたとき、それは @_(グローバルまたはレキシカル)が使用されているかどうかによって異なり、結果がスカラまたはリストとして渡されるかどうかに依存します。
開発者は常にリストを返す関数を書きましたが、スカラコンテキストを考慮していませんでした。この関数をスカラコンテキストで呼び出すと、リストの最後の要素だけが得られます。
利点:
欠点:
関数では wantarray が使用され、リスト、意味のあるスカラ、または undef が返されます。
利点:
欠点: