1. ホーム
  2. スクリプト・コラム
  3. パール

perlのour-my-localスコープ宣言の紹介

2022-02-02 09:47:11

正直なところ、この本は無名なので、ちょっと投げやりな感じですが、難しくはないでしょう。
Our, "confine a name to a certain scope"は、実際にはモジュールや関数の内部で定義され、外部からもアクセス可能なグローバル変数("global variable")を明示的に宣言することで、それが既に宣言されている場合、再度 "our" で、ここでは同じ名前のプライベートまたはローカル変数ではなくグローバル変数が使われるということだそうです。

コピーコード コードは以下の通りです。

our $PROGRAM_NAME = "waiter";
{
my $PROGRAM_NAME = "something";
our $PROGRAM_NAME = "server"; #our here is the same as outside, and different from the previous sentence.
# The code called here sees "server"
}
# The code executed here is still seen as "server".

my ,"名前と値をある範囲に制限する"、つまり、このレベルのモジュールや関数だけが変数を見ることができ、上位や下位のレベルのものは見ることができない、ということです。
コピーコード コードは以下の通りです。

sub greeting1{
    my ($hello) = "How are you do?";
    greeting2();
}
sub greeting2{
    print "$hello\n";
}
$hello = "How are you doing?";
greeting2();
greeting1();
greeting2();

走った結果
コピーコード コードは以下の通りです。

How are you doing?
How are you doing?
How are you doing?

greeting1の中でgreeting2を呼び出すと、greeting2にはgreeting1のプライベート変数$helloは表示されず、外のグローバル変数$helloだけが表示されます。
local,"confine to the certain range"は、"dynamic lexical range"とも呼ばれますが、ちょっとわかりにくいですね。私の理解では、この層とこの層より下の関数は、この層の変数を見ることができるが、この層より上の層は見ることができない、ということです。具体的にどの範囲なのかは、この層の関数だけでなく、次の層のプログラムの長さや深さにも依存するので、"dynamic range"と呼ばれているのです。
コピーコード コードは以下の通りです。

sub greeting1{
    local ($hello) = "How are you do?";
    greeting2();
}

sub greeting2{
    print "$hello\n";
}
$hello = "How are you doing?";
greeting2();
greeting1();
greeting2();


走った結果
コピーコード コードは以下の通りです。

How are you doing?
How are you doing?
How are you doing?

myを使ったときとは違いますよね?greeting1がgreeting2を呼び出すと、greeting2にはgreeting1のローカル変数$helloが見え、外部グローバル変数はもちろん非表示になります。