Re: Sharing variables between modules




Quoth Tomek <balrog2000@xxxxx>:
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.

use b;

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

--
Like all men in Babylon I have been a proconsul; like all, a slave ... During
one lunar year, I have been declared invisible; I shrieked and was not heard,
I stole my bread and was not decapitated.
~ benmorrow@xxxxxxxxxxxxx ~ Jorge Luis Borges, 'The Babylon Lottery'
.



Relevant Pages


Quantcast