第1回 use strict; と my

こんばんは。ビンゴ中西です。

bingo_nakanishiのPerlではじめるプログラミング言語
では、プログラムがまったくはじめてという方を対象にPerlという言語を用いてプログラミングの楽しさを知っていただこうと書いてきましたが、本ブログでは、他言語出身の方を対象にPerlを紹介できればいいなと考えております。


他言語としては、 C言語, Java, Ruby, JavaScriptなどを考えています(といっても僕はそれほどこれらについては知らないのですが....)。






ということで第1回目の今日は、「スコープ」についてお話していければなぁと思います。
新しいプログラミング言語を覚えるにあって最も気になる部分のひとつにスコープがあると僕は思っています。


さて、さっそくですが、次のソースを実行してみましょう。

hoge();
foo();

sub hoge {
 $c = 1;
 $d = 2;
}

sub foo {
 print "--- foo ---\n";
 print "$c", "\n";
 print "$d", "\n";
}

結果:

--- foo ---
1
2

結果をみてもらうとわかりますが、 $c と $dはグローバル(大域)となってしまっています。


これは、えらいこっちゃでえええええ!!!!!!


というわけで、スコープの幅を狭めてやる必要があります。
そこで、 my の登場です。次のようにしてみましょう。

hoge();
foo();

sub hoge {
 my $c = 1;
 $d = 2;
}

sub foo {
 print "--- foo ---\n";
 print "$c", "\n";
 print "$d", "\n";
}

$cに、myを付けました。結果はどうでしょうか?


結果:

--- foo ---

2

1行空白で表示されてしまいました。これは、myの力によって、 $cのスコープが、hoge関数の中に閉じ込められたからです。
というわけで、立派なプログラムを書く為には、myが必要なわけですが、$dのようにmyを付け忘れた場合に悲劇が避けられません。


そこで、use strict; の登場です。use strict; を書くと、myの付け忘れを指摘してくれるようになります。

use strict;

hoge();
foo();

sub hoge {
 my $c = 1;
 $d = 2;    # $dにmyが付いていない
}

sub foo {
 print "--- foo ---\n";
 print "$c", "\n";       # fooでは、$cがいないのでprintできない
 print "$d", "\n";       # fooでは、$dがいないのでprintできない
}

結果:

Global symbol "$d" requires explicit package name at a line 8.
Global symbol "$c" requires explicit package name at a line 13.
Global symbol "$d" requires explicit package name at a line 14.

実行すると、このようなエラーメッセージをはかれてしまいます。
エラーが言っているのは、上のソースのコメントに書いたことが原因です。(※ aというとてもわかりづらいファイル名で実行しました)


これで、 use strict; が超大切なことがわかっていただけたと思います。
(※ use strict;の機能はこれだけではありません)



さて、my の宣言部分なのですが、

my ($c, $d);

と一気に2つ宣言することが可能です。
ここで、C言語出身者でよく犯す過ちが、

my $c, $d;

と書くことです。これでは、

my $c;
$d;

と書いたことと同じことになり、 $dにmyが適用されません。

C言語では、

int i, j;

たしかに、このように書けますが、Perlでは、( ) で囲ってあげる必要がありますので注意してください。





ここで、Perlでプログラムを書く上でのコツですが、変数を使いたくなったら、変数を使いたくなったところで、

# 何か処理

my $d = 5;
$d++;

# 何か処理

と用意していくのが、ポイントです。関数の頭にしか変数を用意できない言語出身だと、
関数に入った瞬間に変数をすべて宣言してしまいますが、それでは、ソースコードを読むのがつらくなります。
用意した変数を使わない処理を読んでいるときも、頭に宣言された変数名を覚えておかねばなりません。そんなことをするよりも、使うところで今から使いますよ!という意味で、変数が必要になったところで、変数を宣言するべきです。


スコープの話をもっと深めると、 myのほかに、localとour。 さらに packageの理解も必要になってきますが、今回は、myのみで話を終えておこうかと思います。

localとourについては、以下の記事などがあります(非常にためになります)。

404 Blog Not Found:perl - myとourとscopeと
[Perl] my と local と our の違いについて - 竹迫の近況報告



それではまた〜