型グロブ 再び

過去の日記で勉強した型グロブでしたが、型グロブとリファレンスの関係を勉強していく内に、型グロブの代入について書いたコードが動かなかった原因が判明しました。
まず、前回書いたコードを再掲します。

 # typeglob.pl
 
 my $hoge = "This is hoge string!";
 my @hoge = ("This", "is", "hoge", "array!");
 sub hoge { return "This is hoge sub!"; }
 
 print "$hoge\n";
 print "@hoge\n";
 print &hoge, "\n";
 
 *fuga = *hoge;
 
 print "$fuga\n";
 print "@fuga\n";
 print &fuga, "\n";

実行してみると

Possible unintended interpolation of @fuga in string at typeglob.pl line 14.
This is hoge string!
This is hoge array!
This is hoge sub!
Use of uninitialized value in concatenation (.) or string at typeglob.pl line 13.


This is hoge sub!

のように「初期化されてないよ」というエラー(というか警告)が出てしまって、意図していた結果(hoge string, hoge array, hoge sub が2回表示される)にはならなかったのですが、今見ると原因がすぐに判りました。(勉強の成果かな?)
まず、型グロブの性質を理解していませんでした。
パッケージにはそれぞれ「シンボルテーブル」というものを持っていて、これがパッケージ変数(our)の変数名と変数の実体を結び付けているわけです。そして、型グロブは「パッケージ変数の総称」だったのです。
レキシカル変数(my)とパッケージ変数(our)は異なりますから、myで宣言した変数が型グロブの代入でコピーされるわけはありませんよね……。
sub で宣言した関数はシンボルテーブルに登録されますから、sub だけはちゃんとコピーされていますね。気づけばよかった……。(-_-;
というわけで、正しくはこうなります。

 # typeglob.pl
 
 our $hoge = "This is hoge string!";
 our @hoge = ("This", "is", "hoge", "array!");
 sub hoge { return "This is hoge sub!"; }
 
 print "$hoge\n";
 print "@hoge\n";
 print &hoge, "\n";
 
 *fuga = *hoge;
 
 our ($fuga, @fuga);
 print "$fuga\n";
 print "@fuga\n";
 print &fuga, "\n";

my → our にしました。また、「Possible unintended interpolation of @fuga in string at typeglob.pl line 14.」(@fuga がいきなり登場したので \@fuga の間違いじゃないかという警告)を解消する為に fuga の方も our 宣言しておきました。
実行結果です。

This is hoge string!
This is hoge array!
This is hoge sub!
This is hoge string!
This is hoge array!
This is hoge sub!

ちゃんと、別名として動きました。(^_^)