Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Track down 'Subroutine SomeSubName redefined...' warning 1

Status
Not open for further replies.

goBoating

Programmer
Feb 8, 2000
1,606
US
'Working on an inherited object oriented Perl application. I can't post code, so I'll try to describe the situation. The application has about 70+ custom modules (classes). This application was developed on Windows and runs without complaint there. Recently, I've been tasked with making it work on Linux. It runs now. But, at compile time (or very early run time), it produces a series of complaints saying:
Code:
Subroutine SomeSubNameHere redefined at /path/to/fileA.pm line ##1.
Subroutine secondSubNameHere redefined at /path/to/fileA.pm line ##2.
Subroutine aThirdSubNameHere redefined at /path/to/fileA.pm line ##3.

For the file, fileA.pm, each of the about 20 subroutines produce a line like above.

I think I see what is going on, but, I don't know how to tell where it is. There are lots of dependencies between the 70+ "*.pm" files.

When the app starts up, a 'use' statement pulls in fileA.pm which has some 'use' statements, one of which pulls in fileB.pm. FileB.pm, in turn, has 'use' statements that refer to fileC.pm. Which, in turn, has 'use' statements one of which uses fileA.pm. Note 'fileA.pm' has been 'used' twice. This daisy chain of 'use' statements bites it own tail.

So fileA.pm starts and then the 'use' goes to pick up, fileB.pm, which starts to compile, but, then goes to pick up fileC.pm which starts to compile, but, points back to fileA.pm. This second call to fileA.pm compiles and the sub routines with their namespaces are loaded. Control falls back to fileC.pm which completes loading, then back to fileB.pm and finally back to fileA.pm. Since the namespaces/subroutine names are already loaded for fileA.pm, I get the 'Subroutine SomeSubNameHere redefined...' complaint.

So, I see what is going on. But, I only know one of the 70+ files that is actually involved in the loop. There may be as few as two files. Possibly many more. :-/

My question, does anyone know how to track the compile process to see which files are involved and when? I need to figure out the sequence of the module loading. What path does the daisy chain follow?

If there were 4 or 5 modules, this would be a quick problem. But, with 70+ "*.pm" files, many of which contain multiple packages, many of which refer back and forth to each other, tracking this down is a pain. I need it to take hours, not days.

Thanks,
John

Does any of this makes sense? ;-/

'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
I thought I remembered something like this in my Perl Hacks book...

Hack #74 says to use Devel::TraceUse

Like this:
Code:
perl -MDevel::TraceUse myscript.pl

And gives output something like this:
Code:
Modules used from myscript.pl:
   1.  strict 1.03, myscript.pl line 2 [main]
   2.  warnings 1.03, myscript.pl line 3 [main]
   3.    Carp 1.01, warnings.pm line 134
   4.      Exporter 5.63, Carp.pm line 132
  12.        Exporter::Heavy 5.63, Exporter.pm line 19
   5.  lib 0.5565, myscript.pl line 5 [main]
   6.    Config, lib.pm line 6
  28.  XML::LibXML::SAX 1.70, (eval 5) [XML::SAX::ParserFactory]
  29.    XML::LibXML 1.70, XML/LibXML/SAX.pm line 17
  30.      XML::LibXML::Error 1.70, XML/LibXML.pm line 23
...

The only downside is that you will have to install this module as it probably doesn't come pre-installed with Perl.

Good luck!
 
Beautiful. I knew there had to be way to do this. Stars for you my friend.

'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
Arrggghhhhh..... I though that would work. However, Devel::TraceUse reports the 'uses' of the modules/classes as they are used in run time (the actual calls to each module).

I think I need to track the 'uses' at compile. It is in the loading of the modules that the warning appears. This is really annoying. The application runs. But, I can't send it to a client with this noise burping out every time it is run. I'll keep digging. I may resort to mapping out all 70+ modules and they associated 'use' statements. What a pain.

Thanks anyway, Brian.

'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
change
use warnings;
to
#use warnings;


:D

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Actually I would think that you need to attack the problem.

I don't believe it is a problem of circular use statements. When you look at a properly written module the first thing in it is "package". What this does is give this package its own name space. So it does matter if A module has a XXX() and B module also has a XXX() even if they call each other.

You get the redefined message because the function is declared twice in the same scope (name space).
This causes it:

sub test
{
}

sub test
{
}

Bottom line?

Look at
Subroutine secondSubNameHere redefined at /path/to/fileA.pm line ##2.

Here is the second reference to the same function in the same name space. If this is in a file with package at the top then the only place you should have to look is in that file. If it is outside of that kind of file you need to look in the global scope.


And I just thought of another way I could cause this:
File:
TestA.pm
has
package TestA;

In another directory you Y you have
Y/TestA.pm
package TestA;


And Yet another because you mention Widows is OK and Unix isn't.

To Windows these are the same file:
TestA.pm
testa.pm

To Unix they are not!

And so you might just have mixed cases like:
Testa.pm
package TestA;
 
Follow up. Even the TestA.pm and Y/TestA.pm examples are probably wrong because Perl would probably complain that the file path Y/TestA is not the same as the package TestA.

So look to the case problem.
 
BTW if this was a simple duplicate reference the fastest way to find it might be to just pick the subroutine and search all the files for:
sub ThatFunction

After all this ThatFunction("param") (as in the use is not what you are looking for). The function name is 'new' you have a problem, but if it isn't so generic it should be an easy search.

But I have a feeling that you are actually talking about a filename/module name case problem and that is going to be harder to find.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top