leocharre has asked for the wisdom of the Perl Monks concerning the following question:

a.pm:

package A; use vars qw{$VERSION @ISA @EXPORT @EXPORT_OK}; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(&a); use strict; sub a; sub a { $a = $_[0]; defined $a or $a='a'; print $a; } 1;

The following use of A.pm works fine. script.cgi

#!/usr/bin/perl -Tw use lib 'where/a/pm/resides'; use strict; use A; a; exit;

However, if I add another module that uses A.pm's b subroutine..
B.pm:

package B; use vars qw{$VERSION @ISA @EXPORT @EXPORT_OK}; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(&b); use strict; use A; sub b; sub b { a; } 1;

And make use of this...
script2.cgi

#!/usr/bin/perl -Tw use lib 'where/a/pm/resides'; use strict; use A; use B; a; b; exit;

I get an error on b.. that it's a bareword. But- why? I can turn the call as &b; and it will work, but.. why didn't a need that ? I tried doing use A on B.pm, but it makes no diff- I am so missing something here. What is it?

I read that if you predeclare a sub then you don't need to use () to pass args, do I need to predeclare a sub somewhere else ?

Replies are listed 'Best First'.
Re: predeclaring subs problems
by ikegami (Patriarch) on Mar 17, 2006 at 20:49 UTC

    I don't get the error you describe until I remove the use lib. Without the use lib, the code module "B" is loaded instead of your module "B". You get the error because the core module "B" doesn't export a function called "b". Rename your module from "B" to something else and you'll be fine.

      Maybe I can ask this another way. Here is my module:
      package Module; use strict; use Exporter; use vars qw{$VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS}; $VERSION = '0.01'; @ISA = qw(Exporter); @EXPORT = qw(); @EXPORT_OK = qw(food cook); %EXPORT_TAGS = ( kitchen => [qw(food)], all => [qw(food cook)]); sub cook; sub food; cook { print "cooked $_[0]"; } food { my $food = $_[0]; defined $food or $food = 'apples'; print "$food is food"; } 1;

      My script using this module..

      use Module qw(:all); food('grapes'); food; # this works fine.

      However, when I have another module, that also has

      use Module qw(:all);
      i get an error!
      Undefined subroutine &Module::Module2::div called at /xxxxx/Module/Mod +ule2.pm line xxx

      I read that predeclaring a sub is what allows me to gove it arguments such as  food 'orange'; - This is making me a little loopy.

      I think what's going on here, since use runs once, the main script is immporting &food - an therefore any other modules that may want to call &food, will have to do so as &::food .. is that correct? How do I get &food to be inherited by all the code ? I guess is what i want..

        First, don't post code you didn't run. You're missing the word "sub" in a couple of places.

        Secondly, since the error is in Module2, it would help if you could show it.

        I suspect you did

        use Module qw(:all); package Module2; ... cook(); ...
        when you should have done
        package Module2; use Module qw(:all); ... cook(); ...
        The former imports everything into the wrong package.