uninitialized value
以下のプログラムを動かします.実行結果も特におかしいところはありません.
#!/usr/bin/perl my @arr=(1,2,3,4,5); my @printValue=@arr[3..5]; print @printValue;
実行結果
bash-2.05$ ./sam.pl 4 5
同じプログラムを-wオプションをつけて実行します.
#!/usr/bin/perl -w my @arr=(1,2,3,4,5); my @printValue=@arr[3..5]; print "@printValue\n";
実行結果です.
bash-2.05$ ./sam.pl Use of uninitialized value in join or string at ./sam.pl line 5. 4 5
5行目のprint "@printValue\n";
で初期化していない値を使っていると警告が出ています.しかし,@printValueはその前の行で値を設定しています.初期化していないはずはありません.
この原因はこう言うことです.まず,3行目のmy @arr=(1,2,3,4,5);
では,配列@arrに以下のように値が入ります.
- my @arr=(1,2,3,4,5);
- $arr[0]=1;
$arr[1]=2;
$arr[2]=3;
$arr[3]=4;
$arr[4]=5;
その次の4行目my @printValue=@arr[3..5];
ではこうなります.
- my @printValue=@arr[3..5];
- $printValue[0]=$arr[3]; #この値は4
$printValue[1]=$arr[4]; #この値は5
$printValue[2]=$arr[5]; #この値はundef
そして,エラーが発生したの5行目です.
- print "@printValue\n";
- print $printValue[0]; #4を表示
print $printValue[1]; #5を表示
print $printValue[2]; #undefを表示しようとしてエラー
print @printValue;
で発生した警告の原因は,その前の行my @printValue=@arr[3..5];
にありました.添字が4までしかない配列@arrの5番目の添字を参照しているのが原因です.配列@printValue自身を初期化していないのではなく,配列@printValueの要素に初期化していないものがあるわけです.
3番目から最後の要素までを出力しようと,@arrをスカラコンテキストで使った場合にも注意が必要です.@arrをスカラコンテキストで使うと@arrの「要素数」を返します.@arrの要素数ですから,5です.
#!/usr/bin/perl -w
use strict;
my @arr=(1,2,3,4,5);
my @printValue=@arr[3..@arr]; #スカラコンテキストで@arrを使う.要素数5
print "@printValue\n";
実行結果はこうなります.
bash-2.05$ ./sam.pl Use of uninitialized value in join or string at ./sam.pl line 6. 4 5 bash-2.05$
添字の最大は$#arrです.3番目から最後の要素までなら,こう書きます.
#!/usr/bin/perl -w
use strict;
my @arr=(1,2,3,4,5);
my @printValue=@arr[3..$#arr]; #要素数@arrではなく添字の最大$#arr.添字の最大4
print "@printValue\n";
bash-2.05$ ./sam.pl 4 5
動作環境は,WindowsNT Workstation 4.0+SP6,cygwin 1.3.3,perl 5.6.1,bash 2.05です.