Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

相互に use すると -c で redefine になる

たとえば、Util1.pm と Util2.pm があって、それぞれ相互に use しているとする。
Util1.pm は Util2.pm の関数を使っているし、逆も同様。

Util1.pm
package Util1;
use strict;
use warnings;
use Util2;

sub multiple {
  my ($i, $j) = @_;
  my $sum = 0;
# $sum += $i for 1 .. $j;
  $sum = Util2::add($sum, $i) for 1 .. $j; # ←ここ
  return $sum;
}

sub minus {
  my ($i, $j) = @_;
  return $i - $j;
}

1;
__END__
Util2.pm
package Util2;
use strict;
use warnings;
use Util1;

sub add {
  my ($i, $j) = @_;
  return $i + $j;
}

sub divide {
  my ($i, $j) = @_;
  my $quo = 0;
  while (0 <= $i) {
#   $i -= $j;
    $i = Util1::minus($i, $j); # ←ここ
    $quo++;
  }
  return $quo - 1;
}


1;
__END__

普通に use して使う分には問題ないみたい。

util.pl
use strict;
use warnings;
use Util1;
use Util2;

print Util1::multiple(6, 7), "\n"; #=> 42
print Util2::divide(42, 6),  "\n"; #=>  7


が、perl -c でチェックすると、"redefine" の警告が出る。

$ perl -c Util1.pm
Subroutine multiple redefined at Util1.pm line 6.
Subroutine minus redefined at Util1.pm line 14.
Util1.pm syntax OK
$ perl -c Util2.pm 
Subroutine add redefined at Util2.pm line 6.
Subroutine divide redefined at Util2.pm line 11.
Util2.pm syntax OK


よーするに、コンパイルの時に、モジュールが読み込んでいるモジュールの中に自分があると、そっちを先に解釈しちゃって、その後の肝心の自分の方の解析時には同じpackageで同じサブルーチン名でテーブルがあるから被ってますよ、とゆー感じなんだろうなと想像。
未確認。
.pl で呼び出したときに警告がでなかったのは謎。


まあ結論としては、つくりが悪いでFA。