疑問:mod_perl と 後置 if と my
#!/usr/bin/perl use strict; use warnings; { my $flg; { my $cnt = 1 if ( $flg ); $cnt++; print "Content-type: text/plain\n\n"; print join( ', ', $cnt, $$, \$cnt ); } } 1;
上記のような CGI を mod_perl(ModPerl::Registry)上で動かすと、Apacheのプロセス毎に $cnt がカウントアップされます。
なぜでしょう??? 誰か教えてください。
$cnt はレキシカルスコープなはずですよね。スコープが外れた {} の後で $cnt を使うと怒られます。なのに、なぜかグローバル変数のように共有されてしまいます。
そもそも、my $cnt = 1 if ( $flg ); はどのように動作するのでしょうか。$flg は undef なので、my $cnt = 1; にはなりません。my $cnt; も実行されないとすれば、$cnt はレキシカルスコープにならず、use strict; でエラーになりそうなものですが、そうはなりません。かといって、初期化(undefがセット)もされない状態になるみたいです。
最後の print のところで、$cnt のリファレンスをscalarとして評価していますが、これを見ると同じメモリアドレスを参照していることが分かります。ということは、このメモリアドレスが初期化されずに、残っている値を参照してしまっているということなのでしょうか。
う〜ん、分かりません。誰か教えてください。
ちなみに、Perl 5.8.8+mod_perl 2.0.2、Perl 5.8.0+mod_perl 2.0.4(+両方ともApache 2.2.11)のいずれで実行しても、同じ結果でした。
#以下追記(2009/08/29)
この記事と同様のことが質問されてました。
http://q.hatena.ne.jp/1251400485
私の記事では mod_perl上での動作についてですが、同じプロセス上であれば同じことが起こるということですね。
確かに、(危険ですが)Hackとして使えないこともないですね(笑)。
http://d.hatena.ne.jp/tokuhirom/20090828/1251448289