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

We have a perl file, test.pl, that looks something like this:
use strict; use test_module; my %hash; $hash{foo} = "bar"; $hash{bar} = "foo"; &test

and we have another file called "test_module.pm" that looks like this:
use strict; sub test { my $test = $main::hash{foo}; print "$test\n"; } 1;
The goal of this exercise is to print the contents of $hash{foo} without passing a reference to %hash as an argument to the sub "test".

I know this example is overly simple, and the solution given this code is just to pass the reference. But this is not possible in our real code.

The above code compiles and runs, but obviously does not work.

Thanks.

Replies are listed 'Best First'.
Re: variables across modules
by chromatic (Archbishop) on Aug 02, 2003 at 20:14 UTC

    You're right, it doesn't work.

    Seriously, %hash is a lexical variable. The whole point of lexical variables is that they're not available outside of their scopes. %hash is scoped to the enclosing file.

    The quick and dirty solution is to make %hash a global variable, probably with the vars pragma. I take issue with this comment, though:

    But this is not possible in our real code.

    It's just software. I change software all the time.

      This "bug/feature" is particularly annoying when changing module code to make use of in-time loading, such as with AutoLoader, SelfLoader and load: your package lexicals cannot been seen by any subroutine loaded at runtime. ;-(

      Liz

Re: variables across modules
by tcf22 (Priest) on Aug 02, 2003 at 20:14 UTC
    Try using our to declare your variables. My only allows access within the scope of Test.pl.

    Test.pl
    use strict; use test_module; our %hash = ( foo => 'bar', bar => 'foo' ); &test;

    test_module.pm
    use strict; sub test { print $main::hash{foo} . "\n"; }
Re: variables across modules
by bobn (Chaplain) on Aug 02, 2003 at 23:09 UTC

    But this is not possible in our real code.

    That may be true, but the solution to get around that may be a cure worse that the disease.

    If you passed a reference, then this code would be more re-usable. As it stands now it's a one-off, an I wonder why you're bothering. I suppose there's some reason in the real code, but this still looks counter-productive to this observer.

    --Bob Niederman, http://bob-n.com