bob_dobalina has asked for the wisdom of the Perl Monks concerning the following question:

i'm coming from .NET, where in each file, you define all your includes. I seem to have trouble with including common libs in perl and want to know the proper way to do this - here's an example i have issues with:
main.pl: ------------ use Common.pm use MyLib.pm MyLib.pm ------------ use Common.pm
If I don't inherit Exporter in Common.pm, i get a bunch of "subroutine redefined errors" which I'm assuming is because main.pl and MyLib.pm use Common.pm, and MyLib.pm also uses Common.pm?
Anyways - I'd rather not inherit Exporter because I'm not doing anything with it. What are the best practices for including packages,library structure, etc? Thanks

Replies are listed 'Best First'.
Re: use directives
by Herkum (Parson) on Aug 04, 2009 at 20:46 UTC

    subroutine redefined errors has nothing to do with your including 'use' in your library and your script. It implies that you are you have defined a subroutine in the same namespace multiple times. For example, this code would generate that same error.

    package Common; sub my_routine {}; sub my_routine {};

    Without looking at your code that is as much help I can give you.

      thanks for all the responses. Exporter ended up having nothing to do with it, i happened to comment out a using line that got rid of my errors and thought it was Exporter related. my first post was not my real code, just trying to show the using hiearchy. Here's a better example of what I have and how I fixed it.

      Directory Structure:
      • /myapp/
        • /myapp/main.pl
      • /lib/
        • /lib/A/
          • /lib/A/Common.pm
          • /lib/A/MyLib.pm

      psuedo-code
      file: /myapp/main.pl ------------------ use lib '..\lib'; use A::Common; use A::MyLib; file: /lib/MyLib.pl -------------------- BEFORE: use lib '..\lib'; use lib '..\lib\A'; use Common; AFTER: Changing to this fixed it: use lib '..\lib'; use A::Common;

      I should note, there were no subroutines duplicated, when it was erroring it had an "subroutine duplicated" error for every subroutine and constant in "Common.pm" which is why I knew it was an issue with the using statements.
Re: use directives
by Marshall (Canon) on Aug 05, 2009 at 00:55 UTC
    This sequence is completely fine. Main can "use Common" and MyLib can "use Common" too. No problem. Common.pm will be "used" and say any BEGIN{} statements will be run on first occurrence of "use Common", after that no code in Common.pm is run. Do not put .pm after the name in the "use" statement.

    You are doing something with Exporter if you are exporting names from a .pm package module. Package is a name space concept. You don't have to export a name but if you don't, you will have to use the fully qualified package name for it, FOO:some_function_4, etc.

    A sort of generic header for a FOO package module in the FOO package name space looks like this...(name this file FOO.pm). It is possible to have multiple "packages" within one Perl file. I strongly recommend against this practice.

    use strict; use warnings; package FOO; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); use Exporter; our $VERSION=1.0; our @ISA = qw(Exporter); our @EXPORT = qw( some_func_name1 some_func_name2 ); our @EXPORT_OK = qw(some_optional_func_name3);
    The "use FOO"; statement does not imply an inheritance hierarchy. Exporter just puts symbols into a symbol table. The form above is more like a 'C' include statement - not exactly, but similar in concept. To fiddle with OO inheritance, I figure that you need to mess with @ISA. This does inherit from Exporter, but that is what you have to do in order for you to export names into from the FOO package name space so that other modules can see them.
      @ISA is only related to OO inheritance. You have its relationship with Exporter reversed: @ISA/inheritance does not depend on Exporter, Exporter uses inheritance ("MyModule is-a Exporter"). Most OO Perl modules do not use Exporter at all, since there's rarely a reason to export symbols into someone else's namespace if they're going to be using an OO interface to talk to you.

      Also, you can do (single) inheritance without (directly) messing with @ISA, thanks to use base. use base 'Exporter'; is equivalent to use Exporter; our @ISA = qw(Exporter);.

      Finally, I just noticed as I was finishing up that last sentence that you're declaring the variables in your example with both use vars and our. One or the other is sufficient, you don't need to do both. (Which of the two is preferred is a matter of taste, but they're functionally equivalent.)

Re: use directives
by ssandv (Hermit) on Aug 04, 2009 at 21:29 UTC
Re: use directives
by plobsing (Friar) on Aug 04, 2009 at 20:48 UTC

    This can't be your real code. I won't even compile. I'm fairly certain use Common.pm is not valid. Perhaps you mean use Common;?

    Are you using package statements at the tops of your modules? If not, everything is going on in the main:: namespace. This would cause "subroutine redefined" errors if your modules define identically named subroutines. Not sure why Exporter would help though.

Re: use directives
by ig (Vicar) on Aug 04, 2009 at 21:31 UTC