local と my の違いが分かるサンプルを書いてみた
our $foo = 0; do { # ... (1) local $foo = 1; do { print "$foo\n" }; # 1 sub { print "$foo\n" } # 0 }->(); do { # ... (2) my $foo = 1; do { print "$foo\n" }; # 1 sub { print "$foo\n" } # 1 }->();
ちなみに do {...} は return の扱いを除いて (sub {...})->() と等価だと考えていいです。まあ、関数をその場で呼び出すようなものですね。単なる {...} との違いは、 {...} が式ではなくて文(ブロック)であって、 do {...} は式(do 関数の呼出し)というところです。
解説
(1) と (2) の do の違いは、構文上含んでいる $foo の宣言が local か my かというところです。
で、それぞれの do の中でさらに do で $foo を参照し、 sub で $foo を参照しています。
do はその場で実行されます。
sub は値(リファレンス)として返され、すぐに実行されます。
そうすると、ソースのコメントに書いてあるような結果が標準出力に出力されます。
なぜ、そうなるのか
構文上のスコープ
package main | | our $foo | | do | | | | local $foo | | | | do | | | | | | $foo を参照 | | | | | | | sub | | | | | | $foo を参照 | | | | | | | do | | | | my $foo | | | | do | | | | | | $foo を参照 | | | | | | | sub | | | | | | $foo を参照 | | | | | |
これが my, our のスコープ
スタック上のスコープ
perl hoge.pl | | our $foo | | do | | | | local $foo | | | | do | | | | | | $foo を参照 | | | | | | | ここで sub を返す | | | | sub | | | | $foo を参照 | | | | do | | | | my $foo | | | | do | | | | | | $foo を参照 | | | | | | | ここで sub を返す | | | | sub | | | | $foo を参照 | | |
これが local のスコープ
というわけです
><
どうですか><?あってますか?