Cycles in use statements can cause issues. Often hard-to-diagnose problems.
Breaking the cycle by making one of them a just-in-time require instead of a use is often a good solution.
# AAA.pm
package AAA;
use base 'Exporter';
our @EXPORT = qw(aaa);
use BBB qw(bbb);
sub aaa {
my $arg = shift;
return 0 if $arg <= 0;
return 1 + bbb($arg - 1);
}
1;
# BBB.pm
package BBB;
use base 'Exporter';
our @EXPORT = qw(bbb);
# use AAA qw(aaa);
sub bbb {
my $arg = shift;
return 0 if $arg <= 0;
require AAA;
return 1 + AAA::aaa($arg - 1);
}
1;
# main.pl
use AAA;
use BBB;
print aaa(3) + bbb(4), "\n";