myとourというか、どうやらPerlのスコープまだよくわかってなかったみたい。
myで宣言した変数はパッケージじゃなくてスコープに対して所属しているから、シンボルテーブルを覗いて見つかったら逆に問題なんじゃないだろうか。で、一番外側にあるスコープはファイルそのものだから、宣言した行からあと、スコープを抜けるまで、つまりファイルの最後まで存在してる。
myがスコープに属しているというはわかってたのだけど、てっきりpackageにもスコープがあるものとばかり。id:seamlessbiasさんthxです。
えと、つまり、
use warnings; use strict; package main; my $var_main; package foo; my $var_foo;
というコードがあったら、$var_mainも$var_fooのどちらもこのファイルのスコープに属することになるわけか。
たしかに、
use warnings; use strict; package main; my $name; package foo; my $name;
とすると、'"my" variable $name masks earlier declaration in same scope at pkg_test_for_blog.pl line 8.'とおこられた。
package宣言でパッケージのスコープが出来ないということは、同じファイルの中に普通にパッケージを定義しても、レキシカル変数を隠蔽できるというメリットはないわけか。だから、普通はファイルごとにpackageを定義して、それでスコープを制限しているのだな。
一つのファイルで同じことをするとなると、
use warnings; use strict; package main; my $name; { package foo; my $name; }
ってことね。ていうか、この書き方は、かなりリャマ本あたりで見た気がしてきた。
で、一番はじめの疑問にもどろう。ここまでの考察を参考に、fooパッケージのためだけのスコープの中に$nameというレキシカル変数を定義する。さらにそれを、サブルーチンを経由して取り出してみた。
use warnings; use strict; { package foo; my $name = 'foo'; sub get_name {return $name;} } my $name = 'main'; print "$name\n"; print foo::get_name(), "\n";
実行結果は、
main foo
となるので、正しくとりだせている。一番の問題はこのfoo:get_name()がとりだした$nameがどこにあるかだ。普通は、スコープを抜けてからはそのスコープ内のレキシカル変数にアクセスできないはず。でも、foo:get_name()はアクセスできてるわけだ。うーん、なんでだ。明日学校でラクダ本あたりとにらめっこして見るかなぁ。