Sharing variables between modules

T

Tomek

Hello!
I am using Perl 5.8.8 on FreeBSD. I have to admit that I already lost 2
hours on something what should be obvious, but for me it isn't :(
I have 2 files, 1st is a parenting script, and 2nd is an included module.
I want to read from 2nd module a variable set in parenting script.

I have tried:

File 'a':

#!/usr/local/bin/perl
use b;
our $a='a';
$b::a=$a;

File 'b.pm':

package b;
print $a;

Executing 'a' prints just nothing :(
-----------------------------------------------
I also tried the second variant:
File 'a':

#!/usr/local/bin/perl
use b;
our $a='a';

File 'b.pm':

package b;
use base 'Exporter';
@EXPORT=qw{$a};
our $a;
print $a;

Effect is the same :( No data printed :( I am now clueless, what am I
doing wrong ?

Regards, Tomasz Kraus
 
U

usenet

Tomek said:
Executing 'a' prints just nothing :(

That's because (among other reasons) 'a' has no print command.

I don't think you're clear on what modules are or what they do.
use()ing a module isn't the same thing as inserting and executing the
code. You don't export variables from modules; you export subroutines.
You call the subroutine and pass data to it. For example:

#!/usr/bin/perl
use strict; use warnings;
use b qw{ print_stuff }; #this is a subroutine we'll call

my ($one, $two, $three) = (1,2,3);
print "In the parent program: $one $two $three \n";
print_stuff($one, $two, $three); #call the module's sub, pass data
__END__

The 'b' module looks like this:

sub print_stuff {
my ($foo, $bar, $baz) = @_;
print "Module got this info: $foo $bar $baz \n"
}
1;
 
M

Mumia W. (reading news)

Hello!
I am using Perl 5.8.8 on FreeBSD. I have to admit that I already lost 2
hours on something what should be obvious, but for me it isn't :(
I have 2 files, 1st is a parenting script, and 2nd is an included
module. I want to read from 2nd module a variable set in parenting script.

I have tried:

File 'a':

#!/usr/local/bin/perl
use b;
our $a='a';
$b::a=$a;

File 'b.pm':

package b;
print $a;

Executing 'a' prints just nothing :(
-----------------------------------------------
I also tried the second variant:
File 'a':

#!/usr/local/bin/perl
use b;
our $a='a';

File 'b.pm':

package b;
use base 'Exporter';
@EXPORT=qw{$a};
our $a;
print $a;

Effect is the same :( No data printed :( I am now clueless, what am I
doing wrong ?

Regards, Tomasz Kraus

Shouldn't that be the other way around? The module that you're use-ing
defines the variables, and the other module prints those values.
 
U

usenet

Mumia said:
Shouldn't that be the other way around? The module that you're use-ing
defines the variables, and the other module prints those values.

I think the OP is confusing use() and do().
 
B

Ben Morrow

Quoth Tomek said:
Hello!
I am using Perl 5.8.8 on FreeBSD. I have to admit that I already lost 2
hours on something what should be obvious, but for me it isn't :(
I have 2 files, 1st is a parenting script, and 2nd is an included module.
I want to read from 2nd module a variable set in parenting script.

I have tried:

File 'a':

#!/usr/local/bin/perl

You *always* want

use strict;
use warnings;

here.

Don't use lowercase module names. They are reserved for pragmata
(modules that affect how perl parses your program).
our $a='a';

Don't use the variables $a and $b. They are slightly magic (they are
used by the sort function) and don't need to be declared. This makes
things harder to debug.
$b::a=$a;

This is occuring too late. The 'print $a;' below happens as soon as the
'use b;' line is compiled, which is before any of the code in 'a' is
run.
File 'b.pm':

package b;

You need

use strict;
use warnings;

here, as well, as their effects are limited to the lexical scope they
are used in: in this case, the file.
print $a;

If you'd used warn instead of print here, it would have been clear that
the statement was in fact being executed but the variable was not set
yet.

If you really want to do something like this, you want

#!/usr/bin/perl

use warnings;
use strict;

# The BEGIN makes the assignment happen at compile time.
# Note that this must also come *before* the use Foo line.

BEGIN { $Foo::foo = 'foo' }

use Foo;

__END__

package Foo;

use warnings;
use strict;

print $foo;

1;
I also tried the second variant:
File 'a':

#!/usr/local/bin/perl
use b;
our $a='a';

What is the 'our' there for? Do you know what it does?
File 'b.pm':

package b;
use base 'Exporter';
@EXPORT=qw{$a};
our $a;
print $a;

Here, again, $b::a is being set too late, after the print command has
already happened.

What are you actually trying to acheive here? Doing real work (as
opposed to initialisation) in the body of a module is generally
considered bad practice: it is much better to export subs from the
module. If your intention was that $a be some sort of setting for your
module, then it is usual *not* to export it but to set it by its full
name in the calling program. If the module's actual work were to be put
in a sub, then you can set the variable before you call the sub,
something like

package Foo;

use strict;
use warnings;

# 'use base' does some odd things to make 'fields' module work.
# It's generally considered better not to use it for Exporter.

require Exporter;
our @ISA = 'Exporter';

# Putting stuff in @EXPORT is usually considered bad style, as
# @EXPORT_OK makes it clearer where things are imported from.

our @EXPORT_OK = qw/do_stuff/;

# It's usual to use Titlecase for package globals, so they stand out
# in the code. This is similar to using ALL_CAPS for constants.

our $Setting;

sub do_stuff {
warn $Setting;
}

1;
__END__

#!/usr/bin/perl

use strict;
use warnings;

use Foo qw/do_stuff/;

$Foo::Setting = 'foo';
do_stuff;

__END__

Ben
 
B

Ben Morrow

Quoth (e-mail address removed):
That's because (among other reasons) 'a' has no print command.

This is not the problem. The print statement is executed, just earlier
than the OP thought.
I don't think you're clear on what modules are or what they do.
use()ing a module isn't the same thing as inserting and executing the
code. You don't export variables from modules; you export subroutines.

While it is not common, you most certainly *can* export variables from
modules. The 'vars' module, for instance, exists solely to export
variables. Other examples are the Socket module, which exports $LF, $CR,
and $CRLF, and the FindBin module, which exports $Bin.

You are correct, of course, that it is generally better practice to
export subs and pass arguments to them, but TMTOWTDI :).

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top