Perl - Package/Module Issues

perl, perl-module

Solution

When you use a module, the code in the module is run at compile time. Then import is called on the package name for the module. So, `use Foo;` is the same as `BEGIN { require Foo; Foo->import; }`

Your code worked without the `package` declarations because all the code was executed under the package `main`, which is used by the main application code.

When you added the `package` declarations it stopped working, because the subroutines you defined are no longer being defined in `main`, but in `UtyDate`.

You can either access the subroutines by using a fully qualified name `UtyDate::CurrentDate();` or by importing the subroutines into the current name space when you `use` the module.

UtyDate.pm

package UtyDate;
use strict;
use warnings; 

use Exporter 'import';

# Export these symbols by default.  Should be empty!    
our @EXPORT = ();

# List of symbols to export.  Put whatever you want available here.
our @EXPORT_OK = qw( CurrentDate  AnotherSub ThisOneToo );

sub CurrentDate {
    return 'blah';
}

sub AnotherSub { return 'foo'; }

Main program:

#!/usr/bin/perl
use strict;
use warnings; 

use UtyDate 'CurrentDate';

# CurrentDate is imported and usable.    
print CurrentDate(), " CurrentDate worked\n";

# AnotherSub is not
eval {  AnotherSub() } or print "AnotherSub didn't work: $@\n";

# But you can still access it by its fully qualified name
print UtyDate::AnotherSub(), " UtyDate::AnotherSub works though\n";

See Exporter docs for more info.

Problem

From everything I've read on using Perl modules, the basic usage is: - Module file with `.pm` extension, which includes the statement `package <name>`, where `<name>` is the filename of the module without the extension. - Code file that uses module contains the statement `use <name>;`. The application I'm coding has one main code script which uses about 5 modules. I had forgotten to include the `package <name>` statement in the modules, but my code still ran just fine with the `use <name>` statement. I started receiving `Undefined subroutine` errors with one of the modules, so I added the package statement to each of the modules. Now the rest of those modules stopped working. What gives? Example: mainapp.pl ``` #!/usr/bin/perl use UtyDate; my $rowDate = CurrentDate("YYYYMMDD"); ``` UtyDate.pm ``` #!/usr/bin/perl package UtyDate; sub CurrentDate { #logic } return 1; ``` When I run the above code, I get the error `Undefined subroutine &main::CurrentDate called at...`. However, if I remove the `package UtyDate;` line from UtyDate.pm, I get no error. This situation exists for several but not all of my modules. There's obviously a lot more code I'm not showing, but I'm confused how any of the code I'm not showing could affect the package/use constructs I've shown here.

Original source