§3.5 コンテキスト


作成日:2001/07/06(金)

この節ではタイトルにもあるように、「コンテキスト」という概念についてお話します。 この「コンテキスト(context)」という言葉、辞書でひくと「文脈」、「前後関係」などと出ています。 Perlではこのコンテキストという概念はとても重要で、でもとてもわかりにくい概念です。 じっくりゆっくり見ていきましょう。

コンテキストとは?

Perlによるプログラミングでは、たくさんの関数や演算子を用います。 これまでにもいろんな関数を見てきました。 これらの関数や演算子は、「値(引数)を受け取って、何らかの操作をし、戻り値(演算結果)を返す」という一連の操作をします。 プログラミングでは、この「値を計算する」という事を「評価する」という言い方をします。 例えば「関数の値を計算する」というのは「関数を評価する」という言い方になります。
 さて、「コンテキスト」というのは、関数や演算子が演算結果を返すときに、どのような値を返して欲しいのかという情報のことです。 関数や演算子をどんな状況で評価したかによってどのコンテキストで結果を返すかが決まります。 コンテキストにはいくつか種類がありますが、代表的な物はスカラーコンテキストとリストコンテキストです。

スカラーコンテキスト

スカラーコンテキストでは、関数や演算子はスカラー、つまり1個の文字列や数値等を返します。 例えば、もう何度も出て来た、

 $x = 3;

の場合、右辺の3という数値がスカラーコンテキストで評価されたということになります。

リストコンテキスト

リストコンテキストでは、関数や演算子はリストを返します。 一番簡単な例は配列への代入です。

 @a = @b;

このように書くと、右辺の配列@bはリストコンテキストで評価されます。 配列をリストコンテキストで評価するとその全部の要素からなるリストが返されます。 そして、そのリストが左辺の配列@aに代入されます。 つまり、@bの全部の要素が@aに代入されることになります。 

では配列をスカラーコンテキストで評価するとどうなるのでしょうか? 例えば、

 $a = @a;

とするとどうなるのでしょうか? 配列をスカラーコンテキストで評価すると、その配列の要素数が代入されます。 なので上の場合は$aには@aの要素数がセットされます。

さらに、リストをスカラーコンテキストで評価するとどうなるでしょうか? たとえば、

 $a = ('a', 'b', 'c', 'd');

とすると、右辺のリストはスカラーコンテキストで評価されます。 この場合、配列とは違い、右辺のリストは「リスト」とは認識されません。 Perlにはカンマ演算子(,)という物があり、上の場合にはカンマ演算子が3つ連続した物を、全体として括弧でくくった物と解釈されるのです。 カンマ演算子はその左にある引数(左オペランド)を捨てて、右の引数(右オペランド)を返します。 またカンマ演算子が連続しておかれた場合、左の物から評価が進んでいくので(これを「左結合」といいます)、結局最後に残るのは一番最後の'd'となり、$aには'd'が代入されます。

今度は反対に、スカラーをリストコンテキストで評価するとどうなるでしょうか? 結果はこちらの方が簡単で、右辺のスカラー1つだけの要素を持つリストが返されます。 ですから、

 @a = 3;

とすると、@aは3という1つの要素だけを持つ配列になります。

splice関数再び

Perlの組み込み関数や演算子には、コンテキストによって異なる値を返す物があります。 上で挙げた配列名もその1つですが、ここでは前節で出てきた配列操作の達人、splice関数について紹介します。 まずsplice関数をリストコンテキストで評価すると、削除した要素を返します。 例えば、

 @array = ("can", 43, "masa", 81, "hide", 69);
 @sakujo = splice(@array, 2, 2, "katsu", 49, "tsuyo", 77);

とすると、@sakujoには"masa"と81の2つの要素がセットされます。 これに対し、splice関数をスカラーコンテキストで評価すると、削除した要素のうちの最後の物を返します。 ですから、

 @array = ("can", 43, "masa", 81, "hide", 69);
 $sakujo = splice(@array, 2, 2, "katsu", 49, "tsuyo", 77);

とすると$sakujoには81がセットされます。

無理やりスカラーコンテキストにする

前節で出てきたscalar関数、そのときの説明では「配列の要素数をとってきてくれる」と書きましたが、実はscalar関数はこのためだけの物ではありません。 scalar関数の本当の動作は、1個の引数を受け取って、それがスカラーコンテキストで評価されたときの値を返します。 なのでscalar(@a)とすると、配列@aをスカラーコンテキストで評価したときの値、すなわち@aの要素数を返すのです。

スライスとコンテキスト

§3.2 配列の要素にアクセスするで、配列の複数の要素にアクセスする方法として「スライス」を取り上げました。 スライスのインデクスはリストコンテキストで評価されます。 ですから、

 @a = (0, 3, 4);
 @array[@a];

とすると、@aの中身が展開されて@array[0, 3, 4]としたのと同じになります。 一方、1つの要素にアクセスする場合には、インデクスはスカラーコンテキストで評価されます。 ですから、

 @a = (0, 3, 4);
 $array[@a];

とすると、(配列をスカラーコンテキストで評価するとその配列の要素数を返すので)、$array[3]にアクセスしたことになってしまいます。 また、

 $array[@array] = "owari";

とすると、配列の末尾に"owari"を追加したことになりますが、

 @array[@array] = "owari";
としてしまうと、配列の中身が壊れてしまいます。

コンテキストについては、スカラーコンテキストとリストコンテキストで異なる関数が多々あるので、はじめのうちはそのことにとらわれてしまうかもしれませんが、なれてくるととても便利な概念です。 いろいろな関数について、それぞれのコンテキストで返す値を調べてみるのも面白いかもしれません。
 さてこれで第3章はおしまいです。 次の章では、Perlのデータ型の最後、ハッシュについて紹介します。


「§3.4 配列操作の達人」へ 「§4.1 ハッシュ」へ
ソフトバンク パブリッシング株式会社

Copyright (C) can All Rights Reserved
e-mail:ishiki@mrj.biglobe.ne.jp