my と local どう違う?

ここでは、変数の局所化に使う my と local について解説します。どちらも変数を局所化することには違いないのですが、細かな点で違いがあり、これを理解していないと、想定しない結果となってしまいます。しっかりと押さえておきたいポイントです。

局所化とは

そもそも局所化とは何かを理解しなければいけません(ご理解されている方は飛ばしてください。)。

数十ステップ、数百ステップ程度のスクリプトの場合には、全体を把握しながら作成できるため、あまり気にしませんが、数千ステップ以上のスクリプトともなると、自分でスクリプトを書いていても、どこにどんな変数名を使ったかを忘れてしまいがちです。Perl の場合、宣言しなくても、いきなり変数を使うことができるため、そのようになりがちです。そこで、ある範囲だけに有効な変数として定義することで、他の範囲には影響しないようにすることができます。具体的に、「ある範囲」とは、中括弧 { と } に囲まれた範囲のことです。中括弧内であれば、サブルーチンに限らず、if や while, foreach 等でも同様です。

このように、ある範囲だけで有効になるよう変数を定義することを、局所化と言います。そして、局所化された変数のことをローカル変数と呼びます。ちなみに、スクリプトのどこでも有効になる変数のことを、グローバル変数と呼びます。

ただ単に、Perl スクリプト内で、

$var = 'hello';

とすると、変数 $var は、グローバル変数となります。つまり、スクリプト内のどこでもこの変数の値を参照したり変更することが可能となります。しかし、$var という変数名をすでに使っていることを忘れて、別の場所で、別の目的で $var を使ってしまうと、期待する結果が得られなくなることは明白ですね。そこで登場するのがローカル変数なのです。もしサブルーチン内で、

sub hoge {
    my $var = 'hello';
    ・
    ・
    ・
}

とすると、変数 $var は、そのサブルーチン内だけで有効になり、ほかの場所からは、この変数を参照することができません。数千ステップにもなるような大規模なスクリプトの場合、できる限り再利用ができる部品つまりサブルーチンとして作成していきます。スクリプト全体が、サブルーチンの寄せ集めといっても過言ではないかと思います。その場合、サブルーチンはできる限りブラックボックス化すべきで、その中で使っている変数が、他の場所から影響を受けるようではいけないわけですね。そうしないと、保守性が悪くなり、問題が起こったときにどこをどう直せばよいかを、作成者本人ですらわからなくなってしまいます。複数人で作成するようなプロジェクトの場合には、なおさらです。そのために、サブルーチンが使う変数は、他から影響を受けないようにしなければいけないわけです。

私の経験上、ほとんどの変数は、ローカル変数として定義しても差し支えありません。グローバル変数として定義するのは、スクリプトの設定値などの定数くらいですね。すでに紹介したように、変数を局所化する関数として、my と local があります。このコーナーでは、それらの違いを解説していきます。