Perlにはスカラーコンテキスト、リストコンテキスト(他にもブール値コンテキスト、無効コンテキスト等々)という概念があるが、これらのおかげで柔軟なコーディングをすることが出来るようになる。
例えば"localtime"という関数は単純に日時を返してくれる関数だが

$time = localtime;

こうした時と

@time = localtime;

こうした時では変数の中身が異なってくる。 $timeは単純な文字列で

Thu Dec  4 13:04:56 2008

こんな感じだ。

@timeは配列で、中身は

[
  56,
  4,
  13,
  4,
  11,
  108,
  4,
  338,
  0
];

こんな並びになっているが順番に

秒,
分,
時,
日,
月,
年,
曜日,
年初からの経過日数,
サマータイム期間,

を表している。
なので例えば

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime;

よくこんな風にして使う。
オブジェクト指向プログラミングでよく"多態性"というキーワードが出てくるがPerlのこの

"何を要求しているかによって関数の挙動を変えてくれる"

のもある意味"多態性"と呼べるのかもしれない。
ところが、ちょっとした落とし穴もあるのでここで紹介。

ある配列の並びを逆順にしたい時は"reverse"という関数が使える。
以下のような配列があったとして、

my @my_array = qw/Perl Ruby PHP Python Javascript Gauche Haskell/;

この配列に対してreverse関数を適用すると

my @r_array = reverse @my_array;

この@r_arrayの並びが

[
  'Haskell',
  'Gauche',
  'Javascript',
  'Python',
  'PHP',
  'Ruby',
  'Perl'
]

こう、単純に逆さになる。
このreverse関数は文字列に対しても適用することが出来るが、機能も単純に文字列が逆さになるというだけのものだ。

my $str = "Javascript";
my $r_str = reverse $str;

こうすると変数$r_strには"tpircsavaJ"が格納されている。
では

print reverse $str;

とした時はどうだろう。 通常は

tpircsavaJ

が出力されるのを期待するだろう。 ところがこの場合は

Javascript

と出力されてしまう。
ちょっと悩んでしまうかもしれないが次に

print reverse $str, "Python";

を実行してみると何が起きているがが分かってくる。
結果は

PythonJavascript

だ。 $str(ここでは"Javascript")と"Python"が入れ替わって表示されているのだ。
これはprint関数はリストコンテキストで評価しているという事を示している。

この場合は

print scalar reverse $str;

と、scalar関数を呼ぶ事によって期待した値を出力する事が出来る。

カテゴリ:

トラックバック(0)

トラックバックURL: http://blog.beanz-net.jp/beanz_mtos/mt-tb.cgi/37

コメントする