読者です 読者をやめる 読者になる 読者になる

ほとラボ

It works!

Perlで配列リファレンスを使わずに多次元配列を扱えるか?

ウチの研究室の教授に

Perlで多次元配列を扱うにはリファレンス使わないとできないっすよー」

って言ったら

「は?リファレンスとか知らんけど多次元配列使えるし」

って言われてキレそうになったけど、 言われたとおり書いたら使えてしまった。

my @array;

for my $i (0..2) {
  for my $j (0..2) {
    $array[$i][$j] = $i + $j;
  }
}

print $array[2][2]; #=> 4

えっ マジで???

データダンプしてみた

use Data::Dumper;

my @array;

for my $i (0..2) {
  for my $j (0..2) {
    $array[$i][$j] = $i + $j;
  }
}

print Dumper @array;

出力

$VAR1 = [
          0,
          1,
          2
        ];
$VAR2 = [
          1,
          2,
          3
        ];
$VAR3 = [
          2,
          3,
          4
        ];

リファレンスになってるし!!!

これってアレですか、

$array[$i][$j] = $i + $j;

は実は

$array[$i]->[$j] = $i + $j;

の省略形で、

明示的にリファレンスを使ってはいないけど 代入時に勝手に配列リファレンスが作られているってことですか!?

そういう 暗黙の了解的な書き方 ってアリなんですか!!?

なんか納得がいかないので、 Perlに詳しい方ご教授ください(´・_・`)

追記

なぜ納得がいかないのか、もうちょっと追記します。

研究室にあったPerlの本を見たところ、 リファレンスの説明が一切無いのに「こうすれば多次元配列が作れる」との記述があり、 リファレンスの知識なしにそういうTipsに頼ったコードを書くのは危険ではないかと思ったのです。

リファレンスを理解しているプログラマにとっては全く問題はなくとも、 Perl初心者が

$array[$i][$j] = $i + $j;

このようなコード見たら Perlは配列の中に配列を入れることが出来る と勘違いしてもおかしくはないでしょう。

RubyPHPと同じ感覚で多次元配列が作れると勘違いしてしまうと、 普通の一次元配列と同じ感覚で pushforeach を使用してしまって 期待した通りの結果が得られないという罠になりかねません。

例えば

use Data::Dumper;

my @array = (1,2);
push @array, (3,4);

print Dumper @add;

このコードは、実際には

$VAR1 = 1;
$VAR2 = 2;
$VAR3 = 3;
$VAR4 = 4;

が得られますが、勘違いしたPerl初心者は

$VAR1 = 1;
$VAR2 = 2;
$VAR3 = [
          3,
          4
        ];

が得られると期待してしまうかもしれません。

それでは Perlは多次元配列が扱いづらいワケがわからない言語」 と思われても仕方がありません。

したがって、

$array[$i][$j] = $i + $j;

このように多次元配列を作るのは、 文法的に誤りでないとはいえ、 極力控えるべきなのではないかと思うのです。