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

Hi Monks, Due to the vagaries of my perl program, I have this setup:
#Value.pm (no package declaration) sub getValue { ... } 1; #MainModule.pm package MainModule { use ExtraModule; ExtraModule::doSomething(); require Value; $x = 'getValue'; &$x(); #does not work at all } #ExtraModule.pm package ExtraModule { sub doSomething() { require Value; $x = 'getValue'; &$x(); #works fine } }
Can someone please explain why the first time I load 'Value' in ExtraModule 'getValue' gets called without problems while the second time in MainModule, it fails... and how I can do this if I need to call getValue in both MainModule & ExtraModule??? thanks a bunch, Michael

Replies are listed 'Best First'.
Re: requiring pm modules
by itub (Priest) on Nov 03, 2004 at 20:55 UTC
    require only loads a file once. The second require is doing nothing. Since your Value.pm file doesn't have a package declaration, its symbols belong to the package that required it first, that is, MainModule.

    Have you considerd using use and Exporter (and giving a proper package declaration to Value.pm)?

Re: requiring pm modules
by pg (Canon) on Nov 03, 2004 at 20:57 UTC

    Side note: you have symbolic refs in your code. if you turn on use strict, no way it will run, and better turn on strict.

    use strict; use warnings; my $x = 'getValue'; &$x(); sub getValue { return 1; }
      First, i need to use 'require' because the 'Value.pm' comes from a configuration file. Secondly, i have declared at the top of my program:
      use strict; no strict 'refs';
      so no problem there either. :)
        Perhaps your code sample is too simplified and out of context, but I see absolutely no reason for using symbolic references. Heck, even within context I doubt it. I've written dozens of Perl modules and programs and haven't really needed symbolic references, except within the very limited context of exporting symbols or creating methods automatically (which doesn't seem to be the case here).

        Added 3 min later: if you don't know the name of the subroutine beforehand (and that's why you have it in $x), you can achieve a similar result without symbolic references by using object-oriented notation:

        require Value; $x = 'getValue'; Value->$x();

        Note that you'd have to change the getValue subroutine so that it shifts its first argument, which will hold the package name.

        If you really need to use a symbolic ref, you're probably better off doing something like:
        use strict; .. no strict 'refs'; $x = 'getValue'; &$x(); use strict 'refs';
        No need to turn off strict refs for the rest of your program.
Re: requiring pm modules
by Mutant (Priest) on Nov 03, 2004 at 20:48 UTC
    When you say 'does not work at all', what do you mean, ie, error messages? At a guess, you could be clobbering functions in MainModule, which is why it's better to use use instead of require.