ちょっとまったour
http://www.geocities.jp/ky_webid/perl5/025.html
○our変数
my と local に続いて、our変数という変数を説明しておきます。Perl にはこの3つの変数が用意されています。
our変数自身は、レキシカルスコープを持ちます。この変数は、他の変数のスコープが内側にあろうとも、必ず外側にある変数をアクセスしようとします。
#!C:/Perl/bin/perl use strict; use warnings; my $num = 500; function(); print "$num\n"; # 500 を出力 sub function{ my $num = 100; # ここに新しいスコープを作る { our $num = 200; # 一番外側にある $num に 200 を代入 print "$num\n"; # 200 を出力 } print "$num\n"; # 100 を出力 }
出力結果は次のようになります。200
100
500
function関数の内部に、{ } を使って新しいスコープを定義しています。こういう手段を使うことは可能です。この中で our変数を使っています。
our 変数は、一番外側にある変数を隠してしまうような、別の同名変数を無視して、外側の変数にアクセスできるようにします。関数の外に $num があり、function関数の先頭にも $num があるので、普通なら、内側にある $num しかアクセスできないはずですが、our変数を使えば、外側の $num を触れるという訳です。
ここで注意して見て欲しいのは、出力結果の最後に 500 があることです。our変数を使って、一番外側の $num に 200 を代入したはずですが、最後には 500 に戻っていることが分かります。これは、our変数自身がレキシカルスコープを持っているためです。our変数のスコープを抜けたとき、外側の $num の値は元に戻ります。
これ読んだらよくわかんなくなった。
この場合のスコープの中のourってmainパッケージ?
http://d.hatena.ne.jp/yupug/20070222/1172172836
([意]訳)
"my"は、変数( $a )のためにメモリに領域を確保し、
変数( $a )がその領域を指し示すよう割り当てておくが、
"our"は、現在のパッケージのパッケージ変数( $Foo::a )を、
変数( $a )が指し示すように割り当てる。つまり、 "our"はレキスカルスコープであるという点は"my"と同じであるが、
かならずしも、変数を新たに作るわけではない。
ということは、さっきの例でいえば
our $num = 200; # 一番外側にある $num に 200 を代入
これは
my $num = 500;
こいつじゃなくて、mainパッケージにレキシカルな$numを作ってそれに200をセットしてourがそのレキシカルな$numを参照してるよ、ってことじゃないのかなあ。
というわけでやってみる。
#!/usr/bin/perl use strict; use warnings; my $num = 500; function(); print "$num\n"; # 500 を出力 print "scope out $main::num\n"; sub function{ my $num = 100; # ここに新しいスコープを作る { print "scope in $main::num\n"; our $num = 200; # 一番外側にある $num に 200 を代入 print "$num\n"; # 200 を出力 } print "$num\n"; # 100 を出力 }
C:\MyWorks\Perl\our>perl our5.pl Use of uninitialized value in concatenation (.) or string at our5.pl line 20. scope in 200 100 500 scope out 200
あってた(多分)
復習すると
#!/usr/bin/perl use strict; use warnings; # ローカル変数 my $num = 500; function(); # ローカル変数の$num print "$num\n"; # 500 を出力 # パッケージ変数はまだ生きてる print "scope out $main::num\n"; sub function{ # subの中のローカル変数 my $num = 100; # ここに新しいスコープを作る { # この時点ではourしてないのでパッケージ変数がない print "scope in $main::num\n"; # mainパッケージに$numのパッケージ変数作成 our $num = 200; # 一番外側にある $num に 200 を代入 # パッケージ変数を表示 print "$num\n"; # 200 を出力 } # スコープを抜けたので完全修飾名なしでパッケージ変数は使えなくなる # ここはsubのローカル変数 print "$num\n"; # 100 を出力 }
ということだと理解したけどどうだろう。