Is it mandatory that a folder by the name of a package should be present for creating a package?

StackOverflow https://stackoverflow.com/questions/468818

  •  19-08-2019
  •  | 
  •  

Question

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).

Was it helpful?

Solution

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.

OTHER TIPS

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

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top