Rancho
Rancho

Reputation: 309

Use a variable from one file into another

I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm

Something like below

A.pm:

if (condition1) { $x = 'PASSED'; }
if (condition2) { $x = 'FAILED'; }

B.pm:

if ($x=='PASSED') { $y=1; } else { $y=0; }

I tried using require ("A.pm"); in B.pm but it gives me an error global symbol requires an explicit package name which means it is not able to read the variable from require. Any inputs would help

Upvotes: 0

Views: 1367

Answers (2)

David W.
David W.

Reputation: 107040

I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm

We could show you how to do this, but this is a really bad, awful idea.

There's a reason why variables are scoped, and even global variables declared with our and not my are still scoped to a particular package.

Imagine someone modifying one of your packages, and not realizing there's a direct connection to a variable name $x. They could end up making a big mess without even knowing why.

What I would HIGHLY recommend is that you use functions (subroutines) to pass around the value you need:

Local/A.pm

package Local::A;
use strict;
use warnings;
use lib qw($ENV{HOME});


use Exporter qw(import);
our @EXPORT_OK = qw(set_condition);

sub set_condition {
    if ( condition1 ) {
       return "PASSED";
    elsif ( condition2 ) {
       return "FALSED";
    else {
       return "Huh?";
}
1;

Here's what I did:

  • I can't use B as a module name because that's an actual module. Therefore, I used Local::B and Local::A instead. The Local module namespace is undefined in CPAN and never used. You can always declare your own modules under this module namespace.
  • The use lib allows me to specify where to find my modules.
  • The package command gives this module a completely separate namespace. This way, variables in A.pm don't affect B.pm.
  • use Exporter allows me to export subroutines from one module to another. @EXPORT_OK are the names of the subroutines I want to export.
  • Finally, there's a subroutine that runs my test for me. Instead of setting a variable in A.pm, I return the value from this subroutine.
  • Check your logic. Your logic is set that $x isn't set if neither condition is true. You probably don't want that.
  • Your module can't return a zero as the last value. Thus, it's common to always put 1; as the last line of a module.

Local/B.pm

package Local::B;
use lib qw($ENV{HOME});

use Local::A qw(set_condition);

my $condition = set_contition();

my $y;
if ( $condition eq 'PASSED' ) {   # Note: Use `eq` and not `==` because THIS IS A STRING!
   $y = 1;
else {
   $y = 0;
}
1;
  • Again, I define a separate module namespace with package.
  • I use Local::A qw(set_condition); to export my set_condition subroutine into B.pm. Now, I can call this subroutine without prefixing it with Local::A all of the time.
  • I set a locally scoped variable called $condition to the status of my condition.
  • Now, I can set $y from the results of the subroutine set_condition. No messy need to export variables from one package to another.

If all of this looks like mysterious magic, you need to read about Perl modules. This isn't light summer reading. It can be a bit impenetrable, but it's definitely worth the struggle. Or, get Learning Perl and read up on Chapter 11.

Upvotes: 2

Miller
Miller

Reputation: 35198

After you require A;, you can then access the variable by giving it an explicit package name like the error message says.

in B.pm:

my $y = $A::x eq 'PASSED ? 1 : 0

The variable $x will have to be declared with our instead of my.

Finally, use eq instead of == for doing string comparisons.

Upvotes: 0

Related Questions