ProgrammingPerlプログラマー/バックエンド開発者

Perlにおけるコンテキストはどのように機能しますか(スカラー、リスト、ボイド)?コンテキストの選択によってコードの動作が異なる場合の例を挙げてください。

Hintsage AIアシスタントで面接を突破

回答

Perlには、演算子や関数の動作に影響を与えるコンテキストがあります:

  • スカラー (scalar) — 式は一つの値として評価されます。
  • リスト (list) — 式は複数の値のリストとして評価されます。
  • ボイド — 結果は使用されません。

関数や演算子は、コンテキストによって異なる結果を返すことがあります。

例:

my @arr = (1, 2, 3); my $count = @arr; # スカラーコンテキスト:$count = 3 my @copy = @arr; # リストコンテキスト:配列全体がコピーされる my $line = <STDIN>; # 一行を読み取る(スカラー) my @lines = <STDIN>; # 全ての行を読み取る(リスト)

コンテキストは、scalar()関数を使って明示的に指定できます:

my $last_idx = scalar @arr; # 強制的にスカラーコンテキスト

ひっかけ問題

スカラーコンテキストにおいて関数keys %hashはどのような値を返しますか?

回答: ハッシュの要素の数を返し、リストコンテキストのようにキーのリストは返しません。

my %h = (a=>1, b=>2); my $num = keys %h; # $num = 2 my @keys = keys %h; # @keys = ('a', 'b')

このテーマの微妙な点を知らなかったことから生じた実際のエラーの例


物語

あるプロジェクトで、配列の要素数を数えました:

my @items = get_items(); my $cnt = @items;

後に誰かが$cnt = get_items();と代入しようとしましたが、関数がリストを返すことを理解していなかったため、常に一つ目の戻り値だけしか得られず、要素の数が得られませんでした。


物語

ファイルから行を読み取る際:

my $lines = <FILE>;

ファイル全体を取得できると思ったら、最初の行だけが返されました—スカラーコンテキストで一つの行が返されることを考慮していませんでした。


物語

開発者はボイドコンテキストで関数を呼び出し、取得した値を使用しませんでした:

open_my_file(); # 関数はディスクリプタを返しますが、それを保持しませんでした

これがデバッグを難しくしました—関数は動作していましたが、ファイルはどこにも保存されず、エラーもキャッチされませんでした。