tags:

views:

153

answers:

4

Hi,

We are factoring out the common code from our Perl project. One main program should be split into several re-usable modules.

Our program name is *"validate_results.pl"* which contains set of validation commands. We are planning to split this into small modules so that *"validate_results.pl"* should be like:

use Common::Validate_Results;
use Common::Validate_Results::CommonCommands;
use Common::Validate_Results::ReturnCodeValidation;
...

As per my understanding I should create a Common folder and under that *"Validate_Results.pm"* should be present. Again under "Common", *"Validate_Results"* folder should be created and under that "CommonCommands" and "ReturnCodeValidation" folders should be present.

Is it mandatory that all these folders should be present or can we have all the Perl programs in a single folder and logically group them and still use the above way to access the modules (say use *"common::validate_results"* like that).

Appreciate the help in advance.

Thanks, Mathew Liju

+6  A: 

The filesystem hierarchy is required. A::B::C will always be located in A/B/C.pm, somewhere in @INC.

If you have to get around this, read perldoc -f require, specifically looking for the section about subroutine references in @INC. Yes, you can make the module loader do weird things if that's what you really want; but that's not what you want, trust me. Just stick to the convention, like the other 99.9999999% of Perl applications do.

jrockway
Wow, nine nines...
Svante
+3  A: 

If you want to 'use' your modules, then you must conform to the structure. If you want to get around that you can 'require' your modules instead, passing the filename to require.

You really shouldn't do this, though. If you truly don't want to have a directory structure, take it out of the module names (though that can lead to problems in the future if you ever have a module name that conflicts with something more generic from CPAN). Simply add the scripts directory to the INC path via Find::Bin and use the modules directly:

use FindBin;
use lib $FindBin::Bin;

use ValidateResults;
use CommonCommands;
use ReturnCodeValidation;

HTH

Joe Casadonte
+2  A: 

Here's an example of a module and it's sub-modules in the same file:

package Foo;
use strict;
use Exporter 'import';

our @EXPORT = ( 'from_foo' );

sub from_foo { print "from_foo\n"; }

package Foo::Bar;
use strict;
use Exporter 'import';

our @EXPORT = ( 'from_foo_bar' );

sub from_foo_bar { print "from_foo_bar\n"; }

1;

In your program, if you use module Foo (the one with a .pm file):

use Foo;

You will have access to Foo::Bar functions, except only as canonical names (Foo::Bar::from_foo_bar). You can import them like this:

use Foo;
Foo::Bar->import;

Note that you can't do this:

use Foo::Bar;

Because there is no file Foo/Bar.pm.

Mathieu Longtin
Thank you for the example. It really helped me.
Liju Mathew
A: 

The package name in a 'use' command is effectively just a path which ends with a .pm file, so you don't need a folder with the name of every package. In your example, you need folders:

Common
Common/Validate_Results

But you don't need folders:

Common/Validate_Results/CommonCommands
Common/Validate_Results/ReturnCodeValidation

The actual package name in the .pm file does not have to be the same as the name in the 'use' command that loads it. But keeping the paths consistent with the package names is always a good idea.

noswonky
Thank you Noswonky for the example with explanation. It helped me.
Liju Mathew