Home > Archive > PERL Miscellaneous > July 2004 > `our' declaration causing problems with `strict' pragma across files
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
`our' declaration causing problems with `strict' pragma across files
|
|
| Dave Bakhash 2004-07-21, 8:59 am |
| I have a set of executable scripts, all written in Perl. This time,
however, I would like all of these scripts to obtain their globals
from a single, separate file. I would also like all of my Perl files
to use the `strict' pragma:
use strict;
which has been a requirement of mine since I started using Perl.
Here's how I thought to do it. Suppose I have a script, foo:
File: foo
#!/usr/bin/perl
package Foo;
use strict;
BEGIN { require "/path/to/Foo.pm"; }
print $BAR; # uses a global variable `$BAR' defined in Foo.pm
# code follows...
Now, the file Foo.pm will look like this:
File: Foo.pm
package Foo;
use strict;
our $BAR = 'BAR'; # global variable
1;
The problem is that having the `use strict;' in the `foo' executable
file is causing problems, and Perl is complaining:
Variable "$BAR" is not imported at ./foo line 6.
Global symbol "$BAR" requires explicit package name at ./foo line 6.
Execution of ./foo aborted due to compilation errors.
What am I missing? Is there a better way to do this? Is `our' the
wrong declaration to be using here?
thanks,
dave
| |
| Anno Siegel 2004-07-21, 3:57 pm |
| Dave Bakhash <cadet@alum.mit.edu> wrote in comp.lang.perl.misc:
> I have a set of executable scripts, all written in Perl. This time,
> however, I would like all of these scripts to obtain their globals
> from a single, separate file. I would also like all of my Perl files
> to use the `strict' pragma:
>
> use strict;
>
> which has been a requirement of mine since I started using Perl.
>
> Here's how I thought to do it. Suppose I have a script, foo:
>
> File: foo
>
> #!/usr/bin/perl
> package Foo;
> use strict;
> BEGIN { require "/path/to/Foo.pm"; }
"BEGIN { require ... } is nearly equivalent to "use".
> print $BAR; # uses a global variable `$BAR' defined in Foo.pm
>
> # code follows...
>
> Now, the file Foo.pm will look like this:
>
> File: Foo.pm
>
> package Foo;
> use strict;
> our $BAR = 'BAR'; # global variable
> 1;
>
> The problem is that having the `use strict;' in the `foo' executable
> file is causing problems, and Perl is complaining:
>
> Variable "$BAR" is not imported at ./foo line 6.
> Global symbol "$BAR" requires explicit package name at ./foo line 6.
> Execution of ./foo aborted due to compilation errors.
>
> What am I missing? Is there a better way to do this? Is `our' the
> wrong declaration to be using here?
"our" is block scoped, which means its scope can't be bigger than the
file it appear in. You'd need another "our" declaration in every file
that uses the variable.
The standard method to do what you want is exportation. Put this in
Foo.pm:
package Foo;
use strict; use warnings;
use Exporter;
our @ISA = qw/Exporter/;
our @EXPORT = qw/$my_var/;
our $my_var;
$my_var = 123;
1;
and this in Foo:
#!/usr/local/bin/perl
use strict; use warnings; $| = 1;
use MyLib;
print "$my_var\n";
For the details, see "perldoc Exporter".
Anno
| |
| Brian McCauley 2004-07-21, 3:57 pm |
| anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) writes:
> Foo.pm:
>
> package Foo;
> use strict; use warnings;
>
> use Exporter;
> our @ISA = qw/Exporter/;
> our @EXPORT = qw/$my_var/;
>
> our $my_var;
> $my_var = 123;
>
> 1;
> and this in Foo:
>
> #!/usr/local/bin/perl
> use strict; use warnings; $| = 1;
>
> use MyLib;
s/MyLib/Foo/
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
| |
| ctcgag@hotmail.com 2004-07-22, 3:56 am |
| cadet@alum.mit.edu (Dave Bakhash) wrote:
> I have a set of executable scripts, all written in Perl. This time,
> however, I would like all of these scripts to obtain their globals
> from a single, separate file. I would also like all of my Perl files
> to use the `strict' pragma:
>
> use strict;
>
> which has been a requirement of mine since I started using Perl.
>
> Here's how I thought to do it. Suppose I have a script, foo:
>
> File: foo
>
> #!/usr/bin/perl
> package Foo;
> use strict;
> BEGIN { require "/path/to/Foo.pm"; }
>
> print $BAR; # uses a global variable `$BAR' defined in Foo.pm
>
> # code follows...
>
> Now, the file Foo.pm will look like this:
>
> File: Foo.pm
>
> package Foo;
> use strict;
> our $BAR = 'BAR'; # global variable
> 1;
Others have told you how to have Foo export variables into the using
package's name space. I would like to urge you to consider another
solution, which is to fully specify the variable name:
print $Foo::Bar;
The downside of this is that you have to type "Foo::" for each use of those
global variable, which is not much of a downside unless the variables are
used quite extensively. The upside is that it is much easier to remember
where to look for that variable declaration (which, if you use the variable
extensively, is probably hard to forget, but if it used just a few times,
is easy to forget). This explicitness is especially important if the code
will be maintained by others not intimately familiar with it.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
| |
| Anno Siegel 2004-07-22, 3:56 am |
| Brian McCauley <nobull@mail.com> wrote in comp.lang.perl.misc:
> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) writes:
>
>
>
> s/MyLib/Foo/
Oh, missed that one. Thanks.
Anno
| |
| Peter Scott 2004-07-22, 8:56 am |
| In article <cdlpnn$qi2$1@mamenchi.zrz.TU-Berlin.DE>,
anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) writes:
>Dave Bakhash <cadet@alum.mit.edu> wrote in comp.lang.perl.misc:
>
>"BEGIN { require ... } is nearly equivalent to "use".
Except that use won't accept a string like that, the argument has to be a
bareword...
--
Peter Scott
http://www.perldebugged.com/
*** NEW *** http://www.perlmedic.com/
| |
| Anno Siegel 2004-07-22, 8:56 am |
| Peter Scott <Peter@PSDT.com> wrote in comp.lang.perl.misc:
> In article <cdlpnn$qi2$1@mamenchi.zrz.TU-Berlin.DE>,
> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) writes:
>
> Except that use won't accept a string like that, the argument has to be a
> bareword...
True. I should have known that trying to gloss over that wouldn't work :)
Anno
| |
| Dave Bakhash 2004-07-22, 3:57 pm |
| ctcgag@hotmail.com writes:
> Others have told you how to have Foo export variables into the using
> package's name space. I would like to urge you to consider another
> solution, which is to fully specify the variable name:
>
> print $Foo::Bar;
Yeah...well, the thing is that I come from this Common Lisp background,
where we also have packages (i.e. namespaces), and so when two files are
in the same package, their variables should naturally be in that package
by default, so if a variable is defined in one file, it should be
available to another without warnings.
It seems almost as if Perl is making this arbitrary exception just
because the variables are being used across file boundaries, which I'm
not used to.
I don't want to use the Exporter stuff because the whole point is that
the two files are in the *same* package. I just want them to be
shared.
I think the 'use vars ...' stuff would have worked, but I just figured
I'd do:
use strict;
no strict 'vars';
and to hell with trying to appease Perl. God...all these years, and I
still can't say I fully understand `our'.
dave
| |
| Ben Morrow 2004-07-22, 8:56 pm |
|
Quoth cadet@alum.mit.edu (Dave Bakhash):
> I have a set of executable scripts, all written in Perl. This time,
> however, I would like all of these scripts to obtain their globals
> from a single, separate file. I would also like all of my Perl files
> to use the `strict' pragma:
>
> use strict;
>
> which has been a requirement of mine since I started using Perl.
Good. You want
use warnings;
as well: read perldoc warnings for how to temporarily turn off warnings
you know are harmless.
> Here's how I thought to do it. Suppose I have a script, foo:
>
> File: foo
>
> #!/usr/bin/perl
> package Foo;
> use strict;
> BEGIN { require "/path/to/Foo.pm"; }
use Foo;
is better; and you should probably call it Local::Foo or MyApp::Foo or
something to avoid conflict with a CPAN module.
> print $BAR; # uses a global variable `$BAR' defined in Foo.pm
No it doesn't. The global variable in Foo.pm is called $Foo::BAR, as you
were in package Foo at the time. Read perlmod. If you want to be able to
refer to $Foo::BAR as $BAR in your main script, you can 'import' it: for
this, see perldoc Exporter or any of the replacements on CPAN.
> What am I missing? Is there a better way to do this? Is `our' the
> wrong declaration to be using here?
'our' is exactly the right declaration to be using. You just need to
know what your variable is called once you've declared it :).
Ben
--
We do not stop playing because we grow old;
we grow old because we stop playing.
ben@morrow.me.uk
| |
| Brian McCauley 2004-07-23, 3:56 pm |
| anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) writes:
> Peter Scott <Peter@PSDT.com> wrote in comp.lang.perl.misc:
>
> True. I should have known that trying to gloss over that wouldn't work :)
Usually one would do something like:
use lib '/path/to';
use Foo;
Or
BEGIN { require '/path/to/Foo.pl' }
It is IMNSO confusing to use .pm suffix (usually associated with Perl5
modules) for something that's loaded like a Perl4-style library.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
|
|
|
|
|