Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

PERL modules named differently than the package won't export

by kovacsbv (Novice)
on May 14, 2012 at 15:50 UTC ( #970456=perlquestion: print w/ replies, xml ) Need Help??
kovacsbv has asked for the wisdom of the Perl Monks concerning the following question:

Hi, all:

I have different versions of a module, say Utils1.pm and Utils2.pm with different filenames but they all have the same package name. I want a .pl file to be able to use whatever version it wants.

Here's the module:

package Utils; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(Log); # symbols to export on request sub Log { my $message = shift; print STDERR "$message\n"; } # Note that Log() is also called from the Utils namespace: sub Start_app { Log("App started."); # Handle other stuff } 1;

And it exports a few functions that are used at many points int the code. Because the function is used so many places, I want to improve readability by not explicitly referencing the package in app.pl.

Then we have the app.pl:

#This file: app.pl use strict; use warnings; use Utils1; Log("App started");

But I get this when running it:

$ perl app.pl Undefined subroutine &main::Log called at app.pl line 8. $
How do I get Log() imported into main? TIA

Comment on PERL modules named differently than the package won't export
Select or Download Code
Re: PERL modules named differently than the package won't export
by Eliya (Vicar) on May 14, 2012 at 16:48 UTC

    The problem is that if you use a different name in the use statement than what you have named the package, Perl will try to call the import method on the wrong package.  In your case, it tries to call Utils1->import, and, as there is no such package/method, nothing is being called and consequently nothing imported.

    So don't do this.  Or if you really want to, make the appropriate import call yourself. I.e. instead of use Utils1, write:

    BEGIN { require Utils1; Utils->import; }

      Thanks, Eliya.

      That solved the problem. Now I can modify the .pm and use it in a more risk-tolerant .pl and when we're all comfortable that it won't blow up, we can start moving it into other .pl files that are risk-averse.

Re: PERL modules named differently than the package won't export
by dsheroh (Parson) on May 15, 2012 at 10:00 UTC
    I'll second the "don't do this". Given that you don't need to include the package name when referencing an exported symbol, what do you hope to achieve by having two separate source files, with two separate names, which contain alternate implementations of the same package?

      Version control of PMs where different callers (that is, different .pl files) can each choose which version of the PM they want by simply changing the use statement, not multiferous lines that call into the module.

      That is my goal.

      Oh, yeah one more thing.

      Most functions are not exported; they have to be explicitly referenced (to avoid too much namespace pollution). But there are two or three that are used so often it just makes more clutter to require explicit reference.

        I see. I guess that makes (some) sense.

        How about this approach, then:

        As Eliya mentioned, use Utils1; is equivalent to

        BEGIN { require Utils1; Utils1->import; }
        You should, therefore, be able to make the import from the Utils package transparent by editing Utils1.pm to do something along the lines of
        package Utils1; sub import { Utils->export_to_level(1, @_); } package Utils; ...
        This will (assuming I remembered the incantation correctly) make Utils1->import equivalent to Utils->import.


        Although, really, the better approach would likely be to put the two versions of Utils.pm into different library directories (e.g., /usr/local/devel/Utils.pm and /usr/local/stable/Utils.pm), then manipulating @INC (by setting PERL5LIB in the shell or with use lib in the code) so that each program will load the appropriate version.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://970456]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (2)
As of 2014-09-24 01:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (243 votes), past polls