IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

my と local のサンプル

local と my - IT戦記の続き

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 のスコープ

というわけです

><
どうですか><?あってますか?

名前空間については話していません

our と local が同じ名前空間を共有してて、という話や Foo:: や main:: がどうこうと言う話は、名前空間の話なのでスコープとはまた別なのかなという気がしています。