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

Hello, If somebody could help me out with this variable scoping problem, it would be greatly appreciated.

Program a.pl

use strict; use warnings; our ($database); $database = "test1";

Program b.pl

use strict; use warnings; our ($database); $database = "test2";

Program c.pl

require "a.pl"; print "$database\n"; require "b.pl"; print "$database\n"; require "a.pl"; print "$database\n";

The output from program c.pl is as follows:

test1 test2 test2

I would like the output to be as follows:

test1 test2 test1

What am I doing wrong?

Replies are listed 'Best First'.
Re: Variable scoping problem
by haukex (Archbishop) on Nov 25, 2019 at 22:25 UTC

    require only loads each file once. Although there are workarounds (deleting from %INC, or do with additional error checking), I would recommend against the architecture you've shown in general. Perhaps if you could explain what the bigger picture is, we can suggest a better approach.

Re: Variable scoping problem
by hippo (Archbishop) on Nov 25, 2019 at 22:29 UTC

    The second time you try to require "a.pl"; has no effect because a.pl is already loaded. To ensure the other scripts are always executed by c.pl, use do instead of require.

    do "a.pl"; print "$database\n"; do "b.pl"; print "$database\n"; do "a.pl"; print "$database\n";
      use do instead of require

      Yes, but do requires additional error checking to make sure it actually worked (the docs show one example, that could be simplified a bit).

        Thank you. I replaced "require" with "do" and the program now works.
Re: Variable scoping problem (how is my program running)
by Anonymous Monk on Nov 26, 2019 at 00:35 UTC

    I would like the output to be as follows: What am I doing wrong?

    Why would you like the output to be as follows? What are you actually trying to accomplish?

    Is this a test/quiz question?

    Or

    What book are you learning from?

    Have you read require?

    This is how you should write that program

    my $database = LoadDatabase('a.pl'); print "$database\n"; $database = LoadDatabase('b.pl'); print "$database\n"; $database = LoadDatabase('a.pl'); print "$database\n"; exit( 0 ); sub LoadDatabase { .... }

    Devel::Trace will trace your program exactly

    >> c.pl:1: require "a.pl"; >> a.pl:1: use strict; ... >> a.pl:2: use warnings; ... >> c.pl:2: print "$database\n"; >> c.pl:3: require "b.pl"; >> b.pl:1: use strict; ... >> b.pl:2: use warnings; ... >> c.pl:4: print "$database\n"; >> c.pl:5: require "a.pl"; >> c.pl:6: print "$database\n";

    As you can see the last require does't execute a.pl because its already loaded

Re: Variable scoping problem
by BillKSmith (Monsignor) on Nov 27, 2019 at 03:47 UTC
    Note that your problem has nothing to do with "variable scoping". There is only one package variable named $database. Neither the variable nor its name ever go out of scope before the end of the program. The value of that variable changes when the required code is executed as other monks have explained.
    Bill
Re: Variable scoping problem
by Anonymous Monk on Nov 26, 2019 at 01:58 UTC
    This is an "old PHP-style" coding technique that today is strongly discouraged even in PHP.

      Citation, please.