in reply to Re^2: error for undefined function that's been imported
in thread error for undefined function that's been imported

What you have should, on the surface, be working.

:DEFAULT should be doing what it says on the tin, but try explicitly naming the subs you wish to import, and see if this works.

One point that occurs to me is that Register.pm could be switching namespaces - with further package declarations. If this is the case, the use will import the subs once - into the package namespace of its context. This is why you need to declare your package first before using Exporter style modules. OO modules don't suffer from this problem as they use a different technique for getting to the namespace.

If you've still got a problem, I suggest dumping out the key stashes (symbol table hashes) after BEGIN has happened, to see whether Exporter has aliased the subs properly. One way to do this is with the debugger (perl -d) - run it up and issue the command:

  DB<1> x %Register::
and see if the sub names appear.

Alternatively, add the following lines to your main program:

use Data::Dumper; print Dumper \%Register::;

--

Oh Lord, won’t you burn me a Knoppix CD ?
My friends all rate Windows, I must disagree.
Your powers of persuasion will set them all free,
So oh Lord, won’t you burn me a Knoppix CD ?
(Missquoting Janis Joplin)

Replies are listed 'Best First'.
Re^4: error for undefined function that's been imported
by argv (Pilgrim) on Aug 15, 2005 at 18:16 UTC

    As I'd pointed out before, I suspected that there was a namespace problem, and your suggestions are good for determining if that's the case. The problem is, what do I do if I make that determination? You passively mentioned this:

    This is why you need to declare your package first before using Exporter style modules.

    Can you elaborate on this? I assume this is something I didn't do, and I don't quite understand how to change the code to meet this requirement. You so quickly mentioned, almost as an aside, that it sounds as though you don't suspect it to be an explanation for the behavior.

      The explanation: when you "use Fred", and Fred.pm exports symbols, these only go into the namespace which is current when you issue "use Fred". They don't go to all namespaces. Consider the following:

      Snark.pm

      package Hunting::Snark; use Bellman qw(foo bar); # Bellman's exported symbols go into namespace Hunting::Snark # hence &Hunting::Snark::foo is aliased to &Bellman::foo package Boojum; foo(); # is an undefined subroutine. There is no &Boojum::foo

      Why I was mentioning that you need to declare a package first before you use things, is that otherwise, any exports will go into main:: not where you want them to. If you declare the package first and immediately above, Exporter will put the symbols into the namespace of the package just declared.

      In terms of fixing your problem, you can add another use statement in the new namespace. This won't re-read the module as it has already been flagged as having been loaded, but the use will redo the Exporter functionality.

      ... package Boojum; use Bellman qw(foo bar); foo(); # &Boojum::foo is now defined. aliased to &Bellman::foo

      --

      Oh Lord, won’t you burn me a Knoppix CD ?
      My friends all rate Windows, I must disagree.
      Your powers of persuasion will set them all free,
      So oh Lord, won’t you burn me a Knoppix CD ?
      (Missquoting Janis Joplin)

        There's a lot going on here, so I want to pick things apart to understand the mechanics. First, your code has:

        package Hunting::Snark; use Bellman qw(foo bar); # Bellman's exported symbols go into namespace Hunting::Snark # hence &Hunting::Snark::foo is aliased to &Bellman::foo package Boojum; foo(); # is an undefined subroutine. There is no &Boojum::foo

        First, why would you have two package statements in a file? that is, I know you can, but I don't see how that alludes to the situation I described (because I'm not doing that). Are you saying that your example illustrates effectively what happens when you use multiple use statements that call other packages into the current file, which is also a package? Is that effectively what I'm doing when I'm doing this:

        package Hunting::Snark; use Bellman qw(foo bar); use Boojum qw(baz etc); foo(); # is an undefined subroutine. There is no &Boojum::foo

        If this is the case, I don't see how any of my code should be working, because (as my first example illustrated), I'm importing packages all over the place, and each of them imports each other. Could it all have been just dumb luck that I haven't started running into this problem more? As my modules are growing, I'm finding this is popping up more frequently.

        What I assumed--and what I'd like to eventually get to--is a way to just have each of my packages have their own uniquely defined functions, export them, and have anyone that uses them simply call them by name without having to clutter up the code with Package::func()-style cruft.

        Now, since that's how I've been operating, and it seems that's not going to be possible (which I'll accept), what's the next best thing? what sort of coding styles might I adopt to alleviate this problem and still have my code look elegant and easy to read/edit by others?