in reply to Redefined subroutines in multiple libraries

If you don't want to make your libraries into modules (which tends to imply object oriented methodology, etc.) you might instead put them into packages. If your familiar with C++, this is the same idea as putting them into a unique namespace.

Here's a real simple example:

This is file MySub1.pm:

package MySub1; use MySub2; sub AAA { my $x = MySub2::DDD(); return "AAA : $x"; } sub BBB { return "BBB"; } 1;

This is file MySub2.pm:

package MySub2; use MySub1; sub CCC { my $x = MySub1::BBB(); return "CCC : $x"; } sub DDD { return "DDD"; } 1;

This is file mytest.pl:

use strict; use MySub1; use MySub2; print MySub1::AAA(), "\n"; print MySub1::BBB(), "\n"; print MySub2::CCC(), "\n"; print MySub2::DDD(), "\n";

Summary: so you have MySub1, a package that contains subroutines, some of which call other subroutines in MySub2; and MySub2 contains subroutines that call subroutines in MySub1. The actual perl script uses subroutines from each of these packages.

Replies are listed 'Best First'.
Re^2: Redefined subroutines in multiple libraries
by chromatic (Archbishop) on Jan 09, 2009 at 22:03 UTC
    If you don't want to make your libraries into modules (which tends to imply object oriented methodology, etc.) you might instead put them into packages.

    There's no difference between modules and packages, and there's no reason why one has to imply any particular style of programming. Why make a distinction?

Re^2: Redefined subroutines in multiple libraries
by James Board (Beadle) on Jan 09, 2009 at 22:57 UTC
    scorpio17: The example you provided illustrates the problem, but doesn't solve it. Try adding "use strict; use warnings;" to each and run MySub1.pm:

    > MySub1.pm Subroutine AAA redefined at MySub1.pm line 9. Subroutine BBB redefined at MySub1.pm line 14.
    As far as I can tell, putting the files into packages has no effect, at least not with respect to this problem. If I remove the package statements from each file, the same warning occurs.

    Jim

      Don't execute modules as scripts.
      perl -e"use MySub1"
      will be clean.
        A note on why this happens. When Perl goes to load a module, it first checks whether it has ever started to load that module and then skips it if it has. So in your use example when you use MySub1 it marks that off, and decides to load MySub2. When it loads MySub2 it realizes it needs to load MySub1, but realize it started that already, and so skips it. It then loads the rest of MySub2, then loads the rest of MySub1 and continues.

        So there is no re-definition warning because you do not try compiling MySub1 twice. But the lack of the warning does not mean that things are necessarily OK. There are nasty lurking potential problems around the fact that when MySub2 completes it expects MySub1 to be there and it isn't. So if, for instance, MySub1's import method has not been created at the point in time where MySub2 is encountered, then that import will not happen. And this failure to run the not yet defined import will be silent! The resulting errors can be extremely mysterious.

        Unless you know exactly what you are doing here, and why, here be dragons.