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

According to the Book, "Packages are independent of files. You can have ... a single package that spans several files" (Chapter 10: Packages).

How can we split the default (main) package into multiple files and link them in the correct order when we compile and run?

Thanks!

Edit:

PS. I know how to organize codes using Perl modules. This question is not about how to write Perl modules or even how to split Perl modules into multiple files with .al extensions.

  • Comment on How to split main package into multiple files

Replies are listed 'Best First'.
Re: How to split main package over multiple files
by GrandFather (Saint) on Jun 23, 2016 at 03:40 UTC

    You can , but don't. Use packages to organise code. If you are splitting code into multiple files there is an implication that you are organising the code into related lumps. If you give each lump a name you have effectively a package name, so use it as an actual package name. The value of good names is that you are providing information that helps organise and find code and that helps write and maintain the code.

    Instead of creating UberPackageWithAllMyJunk create multiple small focused packages with appropriate names like CatGrooming, DogGrooming and BasicGrooming so you have some idea of how the code fits together and where to look for solutions to specific problems. (Did you spot that the dog and cat grooming packages probably use the basic grooming package?)

    Premature optimization is the root of all job security

      GrandFather, thank you for the good advice. Although I appreciate the wisdom behind your suggestion, I really need to try a few ideas after splitting the main package into multiple files -- if it is possible at all.

Re: How to split main package over multiple files (main is for programs)
by Anonymous Monk on Jun 23, 2016 at 00:30 UTC
Re: How to split main package over multiple files
by Kordaff (Scribe) on Jun 22, 2016 at 23:38 UTC

    Split them out of the file below, uncomment the use lines. The modules run in the order that they are 'use'd in and then test.pl runs.

    Probably best to only have global scope code run from one of the files, but ymmv.

    --kordaff

    #!/usr/bin/perl use warnings; use strict; print "This is test.pl\n"; # use main_1; # use main_2; # use main_3; ########## main_1.pm ############################# package main::; print "this is main_1\n"; ################################################## ########## main_2.pm ############################# package main::; print "this is main_2\n"; ################################################## ########## main_3.pm ############################# package main::; print "this is main_3\n"; ##################################################

      Thank you, Kordaff.

      Your program (after uncommenting use pragmas) produces this output:

      this is main_1 this is main_2 this is main_3 This is test.pl

      Changing main_1.pm to this

      ########## main_1.pm ############################# package main::; sub test1{ print "This is test1 in main_1\n"; }
      produces this:
      main_1.pm did not return a true value at test.pl line 4. BEGIN failed--compilation aborted at test.pl line 4.

      This was not surprising, because as its filename extension indicates, main_1.pm was a perl module, not a part of test.pl; thus, it required "1;" at the end of the file, so that it would be evaluated as TRUE. As soon as I appended it there, the error went away.

      This approach also does not share the namespace with test.pl. Let's consider this alteration on test.pl:

      #!/usr/bin/perl use warnings; use strict; use main_1; use main_2; use main_3; print "This is test.pl\n"; &test1;

      We would see the following output.

      this is main_2 this is main_3 Undefined subroutine &main::test1 called at test.pl line 8. This is test.pl

      In order to correct this problem, we have to do the following alterations in main_1.pm.

      ########## main_1.pm ############################# package main::main_1; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(&test1); sub test1{ print "This is test1 in main_1\n"; } 1; ##################################################

      Note first that &test1 needs to be exported. However, that by itself is not sufficient -- we also have to assign the actual (missing) name of the module as I have done on the first line of the code. For some reason, Perl had been tolerating the lack of proper name, in the earlier versions of this code.

      Now, we get a proper output:

      this is main_2 this is main_3 This is test.pl This is test1 in main_1

      That said, I am not interested in writing the code that needs to be part of the main package into a new module.

      I appreciated your suggestions.