同じモジュールを複数回useしたときの挙動とかシンボルテーブルとか
神ネタ。もう神タグ作ろうかな。
perlではモジュールをuseすると、use元のシンボルテーブルに、そのモジュールをuseしたよっていうフラグみたいなものが付くらしい。
で、同じモジュールを複数回useしても、そのフラグを見て、既にuseされてたらuseの処理は走らない、らしい。
Mod.pm
package Mod; use base qw/Exporter/; use strict; use warnings; our @EXPORT = qw/hoge/; sub hoge { 1 } 1;
main.pl
use strict; use warnings; use Mod; sub hoge { 2 }
ここでいうと、use Modにより、main::の名前空間にhogeという関数がエクスポートされる。
で、main.plの中でもhogeという関数を定義する事で、redefineな警告が出る。
% perl main.pl Subroutine hoge redefined at main.pl line 5.
Mod.pmを複数回useして、redefineな警告が複数回出るなら、useする度にuseの処理が走ってるってことになる、と。
main.pl
use strict; use warnings; use Mod; use Mod; use Mod; sub hoge { 2 }
% perl main.pl Subroutine hoge redefined at main.pl line 7.
なるほど確かにuseの処理は1度しか走らないようだ。
んじゃuseしたフラグとやらを消してみよう。
main.pl
use strict; use warnings; BEGIN { delete $INC{q{Mod.pm}}; use Mod; } use Mod; sub hoge { 2 }
% perl main.pl Subroutine hoge redefined at Mod.pm line 7. Subroutine hoge redefined at main.pl line 10.
useの処理が2回走ったようだ。BEGINとuseの処理の優先順位は分からんけど、BEGINの前にuse Mod書くと1度しか警告出ないから、えーとBEGINが先?
神ネタここまで。ここから俺ネタ。
と、ここまで書いておいて何なのだけど、複数回同じモジュールをuseしてフラグ消さない場合でも、useの処理は一部分だけ走ってんじゃね疑惑。
Mod.pm
package Mod; use base qw/Exporter/; use strict; use warnings; our @EXPORT = qw/hoge/; sub hoge { 1 } sub import { __PACKAGE__->export_to_level(1,@_); warn "use Mod"; } 1;
main.pl
use strict; use warnings; use Mod; use Mod; use Mod; sub hoge { 2 }
% perl main.pl use Mod at Mod.pm line 11. use Mod at Mod.pm line 11. use Mod at Mod.pm line 11. Subroutine hoge redefined at main.pl line 7.
importは「use済みフラグ」が立っててもちゃんと実行されると。何が何やら。