第4章 サブルーチン Perlは変数のスコープがアレだなぁ

サブルーチンの章をいっぺんに読んだ。まず、ためしにサブルーチンを書いてみる。

sub adder {
    my ($x, $y) = @_;
    $x + $y
}

print &adder(1, 2) . "\n";

軽ーくまとめておこう。

  • subでサブルーチンを定義する
  • サブルーチン名に&を付けると呼び出せる
  • 引数は()で渡せ!
  • サブルーチン内では引数のリストは@_というローカルな変数に入れられる
  • 最後に評価された式の値が戻り値
  • サブルーチン内でプライベートな変数を使いたい時はmyを使う

最後に評価された値ってのはRubyっぽいね。むしろ、Rubyの機能の原典はPerlなんだろうけど。

さてさて、うちは気づきましたよ。Perlの変数のデフォルトのスコープがグローバルってことにな!きちんとmyしないとどこからでも参照できちまう。Cをはじめ、PythonやRubyを見てきたうちとしては、なんというか、キモい?(失礼な)

それはともかく、変数のスコープについていろいろ調べてみよう。

さすがにサブルーチン実行されるまでは、グローバル変数といえどなにか代入されたりしないよね。

sub only_assign {
    $ktkr = 'キタコレ';
}

print $ktkr."\n";

これを-wつきで実行すると、

$ ./mine4-1.pl
Use of uninitialized value in concatenation (.) or string at ./mine4-1.pl line 5.

と返された。サブルーチン実行してないんだし当たり前よね。

sub only_assign {
    $ktkr = 'キタコレ';
}

&only_assign();
print $ktkr."\n";

こうした結果は、

$ ./mine4-1.pl
キタコレ

キタコレ。サブルーチン内で定義した$ktkrがプログラムのトップレベルで使えてしまいました。がくぶる。

で、ここでmyを使うというわけですね。

sub only_assign {
    my $ktkr = 'キタコレ';
}

&only_assign();
print $ktkr."\n";

結果は、

$ ./mine4-1.pl
Name "main::ktkr" used only once: possible typo at ./mine4-1.pl line 6.
Use of uninitialized value in concatenation (.) or string at ./mine4-1.pl line 6.

となる。myで宣言した$ktkrはいっぺんも使われてないよっていうエラーが出てはいますが、これはあたりまえ。とりあえず、「キタコレ」とは表示されていないのでグローバルからは$ktkrにはアクセスできてないよね。このへんは予想どおり。

サブルーチンに限らず、myをブロックの中で使うと、指定した変数をそのブロックでプライベートにする。また、プログラムのトップレベルでもmyは使える。

ifもブロックの一つなので、上のことが成り立ってるか確かめてみよう。また、ブロックの中に別のブロックをおくとどうなるのか。ifとかでかなりこまると思うので、ブロックの内側にあるブロックからは、その外側のブロックで(myで)宣言された変数が見えるはずだ。ここでは、一番外側のブロックのかわりにプログラムのトップレベルを使ってる。

#$uhoはこのifブロック内でプライベート
if(1) {
    my $gj = 'じーじぇい';
}
print $uho."\n";


#トップレベルでmyを宣言
my $ksk = '加速';

#ifのブロックの中から参照できる?
if (1) {
    print $ksk."\n";
}

これの結果が、

$ ./mine4-1.pl
Name "main::uho" used only once: possible typo at ./mine4-1.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./mine4-1.pl line 7.

加速

となる。予想どおり。なんとなく、感覚がわかってきたかしら。すくなくとも、外側のブロックから内側のブロックの(myされた)プライベート変数にはアクセスできない。でも、内側から外側へのアクセスはもう少し融通が利きそうだ。もうちょい詳しく確認する必要がありそう。

ともあれ、本日からはuse strictしていきたいと思います。

初めてのPerl

初めてのPerl

  • 作者: ランダル・L.シュワルツ,トムフェニックス,Randal L. Schwartz,Tom Phoenix,近藤嘉雪
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2003/05
  • メディア: 単行本
  • 購入: 15人 クリック: 474回
  • この商品を含むブログ (294件) を見る