グローバル変数のローカル化

Perl ベストプラクティス」より。グローバル変数 $a をローカル化しようとした場合、以下のようにすると、正しく動きそうだが、実際は期待通りの結果にならない。

     1  $a = 'aaa';
     2  {
     3    warn $a;
     4    local $a;
     5    
     6    warn $a;
     7  }
     8  warn $a;

実行結果は下記:

aaa at script.pl line 3.
Warning: something's wrong at script.pl line 6.
aaa at script.pl line 8.

ローカル化された $a は undef となるのだ(4行目でローカル化された $a を6行目で表示させようとして、undef)。期待通りの動作をさせるには、以下のように、一見無意味に見える記載をする必要がある。

     1  $a = 'aaa';
     2  {
     3    warn $a;
     4    local $a = $a; #グローバル変数 $a の値をコピー
     5    warn $a;
     6  }
     7  warn $a;

これを実行させると、以下のように期待通りの動きになる。

aaa at script line 3.
aaa at script line 5.
aaa at script line 7.

実際にはわざわざローカル化する場合、なんらかの値をセットすると思うので、通常ここでハマることは無いと思うけども。