in reply to Acceptable way to divide a long module into multiple files
That rule exists primarily to make sure that departures from the convention are well thought out, not because Perl will somehow malfunction if package and file name do not match. Very often mismatches are due to (a) typos in pakage or file names or (b) possibly a beginning programmer valuing "I feel comfortable with this name" over "I want to easily find the file that stores my class definition".
Neither (a) nor (b) apply in this case. Your decision to split the module among several files is an intentional choice, not a typo or failure to understand the long term maintenance significance. But you still might want to think twice about splitting the module into multiple parts.
The other reason for package=file name is that in general splitting code between multiple files is not a good idea, even if it looks that way during the green field development phase. Long term, the code tends to be harder to maintain. Follow-on programmers may not realize that there is more than one file storing the class definition unless the multi-file nature of the class definition is clearly documented.
A second issue is that over time dependencies between methods of a class sometimes change. A split class definition needs to be carefully arranged so that each part relies only on the earlier parts in the sequence. If something in the future causes part 2 to need something in part 3, you will have to rearrange the division of code into files. This rearranging would be completely unnecessary were the code not divided among multiple files. Furthermore, rearranging that spans multiple files is always more error prone and more complex to revert than rearranging code in a single file.
Should you decide that the pros of splitting the module definition outweigh the risks, it is important is that your codebase handle these situations in a consistent and well documented manner. Preferably you should use a naming convention that makes it obvious that there are "continuation" files for a module. For example, you might reserve "name_N" for part N of a module "name".
Personally, I prefer the header+parts approach. The header file is named after the class itself and simply loads the parts. It also contains a line reminding the maintainer that the class definition is stored in multiple files. When other projects, use this module, they only know about the header file. The header file is responsible for loading all of the parts:
Sample header file, "My/Mondo/Class.pm"
use warnings; use strict; package My::Mondo::Class; # This class is defined in multiple files - see use My::Mondo::Class_1; use My::Mondo::Class_2; use My::Mondo::Class_3;
The files storing the parts are defined as normal module files, with the ".pm" ending and store the actual class definition. Each of the My::Mondo::Class_N would be stored in a file named, "My/Mondo/Class_N.pm" and begin like this:
use strict; use warnings; package My::Mondo::Class; # methods and variable initializations that depend only # on stuff declared in My::Mondo::Class or earlier parts # in the sequence, i.e. if this is My::Mondo::Class_2 then # it only references variables and methods in # My::Mondo::Class and My::Mondo::Class_1
Also be aware that using variables across many files requires a nuanced understanding of the difference between lexical and global variables. See replies below. This may present training issues.
Also be aware that at least some versions of Perl are a touchy about package variables. If you split a module between two files, say "Foo_1.pm" and "Foo_2.pm", and you define a variable in "Foo_1.pm", then you have to use the fully qualified name in "Foo_2.pm", even if the current package is the same as "Foo_1.pm". This applies to both my and our variables. This issue does not apply to subroutines. They can be used without qualification in all files assigned to the "Foo" package. - (struck out due to tilly's correction below)
#Foo.pm use strict; use warnings; package Foo; use Foo_1.pm; use Foo_2.pm; # Foo_1.pm use strict; use warnings; package Foo; my $HELLO; our $GOODBYE; sub hello { return "Hi!"; } # Foo_2.pm use strict; use warnings; package Foo; #note: also package Foo #$HELLO='Bonjour' #compiler complains - see below for why $Foo::HELLO='Bonjour'; #this is OK - see below for why #$GOODBYE='Au revoir' #compiler complains - see below for why $Foo::GOODBYE='Au revoir'; #this is OK - see below for why # calling hello() without qualification is OK, so long # as the package is Foo (which it is) print hello() . ": Hello=$Foo::HELLO, Goodbye=$Foo::GOODBYE\n";
Note: is this a bug or intended behavior? Behavior noted in Perl 5.8.8) - Update:: definitely intended behavior - see below.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Acceptable way to divide a long module into multiple files
by tilly (Archbishop) on Jan 12, 2011 at 08:07 UTC | |
by ELISHEVA (Prior) on Jan 12, 2011 at 08:57 UTC | |
by tilly (Archbishop) on Jan 12, 2011 at 09:05 UTC |