`our' declaration causing problems with `strict' pragma across files

`our' declaration causing problems with `strict' pragma across files

Post by cade » Thu, 22 Jul 2004 21:26:31


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
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by anno400 » Thu, 22 Jul 2004 22:05:59

Dave Bakhash < XXXX@XXXXX.COM > wrote in comp.lang.perl.misc:

"BEGIN { require ... } is nearly equivalent to "use".


"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

 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Brian McCa » Fri, 23 Jul 2004 01:48:30


XXXX@XXXXX.COM (Anno Siegel) writes:



s/MyLib/Foo/

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Ben Morro » Fri, 23 Jul 2004 05:45:54


Quoth XXXX@XXXXX.COM (Dave Bakhash):

Good. You want

use warnings;

as well: read perldoc warnings for how to temporarily turn off warnings
you know are harmless.


use Foo;

is better; and you should probably call it Local::Foo or MyApp::Foo or
something to avoid conflict with a CPAN module.


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.


'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.
XXXX@XXXXX.COM
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by ctcga » Fri, 23 Jul 2004 12:46:54


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://www.yqcomputer.com/
Usenet Newsgroup Service $9.95/Month 30GB
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by anno400 » Fri, 23 Jul 2004 16:08:06

Brian McCauley < XXXX@XXXXX.COM > wrote in comp.lang.perl.misc:

Oh, missed that one. Thanks.

Anno
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by pete » Fri, 23 Jul 2004 21:30:14

In article <cdlpnn$qi2$ XXXX@XXXXX.COM >,
XXXX@XXXXX.COM (Anno Siegel) writes:

Except that use won't accept a string like that, the argument has to be a
bareword...

--
Peter Scott
http://www.yqcomputer.com/
*** NEW *** http://www.yqcomputer.com/
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by anno400 » Fri, 23 Jul 2004 21:39:30

Peter Scott < XXXX@XXXXX.COM > wrote in comp.lang.perl.misc:

True. I should have known that trying to gloss over that wouldn't work :)

Anno
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Dave Bakha » Sat, 24 Jul 2004 00:18:50


XXXX@XXXXX.COM writes:


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
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Paul Lall » Sat, 24 Jul 2004 00:37:32


I'm not sure if the other responders noticed the whole 'same package' deal
or not.... this works for me:

File: temp.pl
#!/usr/bin/env perl
use strict;
use warnings;

use Foo;

package Foo;
our $bar;
print "Explicit: $Foo::bar\n";
print "Implicit: $bar\n";
__END__

File: Foo.pm
package Foo;
use strict;
our $bar = 'Hello World';

1;



Both print statements output "Hello World\n"; Is that what you're
looking for?


Paul Lalli
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Uri Guttma » Sat, 24 Jul 2004 00:53:21

>>>>> "DB" == Dave Bakhash < XXXX@XXXXX.COM > writes:

DB> and to hell with trying to appease Perl. God...all these years, and I
DB> still can't say I fully understand `our'.

it is much simpler than you realize. it just creates a short nickname in
the current lexical or file scope for a package variable. in some ways
it is just a lexical version of user 'vars'. so you can do our $foo in
two separate files which are in the same package and both $foo's refer
to the same package variable. it also means that fully qualified access
to $foo is still possible.

uri

--
Uri Guttman ------ XXXX@XXXXX.COM -------- http://www.yqcomputer.com/
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://www.yqcomputer.com/
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by anno400 » Sat, 24 Jul 2004 01:50:50

Uri Guttman < XXXX@XXXXX.COM > wrote in comp.lang.perl.misc:

It also means that "our" isn't really a declaration, in the sense that
it tells the compiler you are going to use that variable. Package
variables don't need one, the first usage is implicitly also the
declaration. "our" only enables a shortcut. If it declares anything,
it's the lexical alias (which you're not supposed to know about).

In contrast, a lexical variable is actually created by the "my" statement.
The parallelism between "my" and "our" is really bogus on a deep level,
though superficially the rule 'declare lexicals with "my", package
variables with "our"' works well enough.

Two fundamentally different mechanisms work in tandem to let you deal
with package variables just like with lexicals, even under strict. I
liken it with a sculpture where two wildly different shapes surprisingly
show the same profile from one point of view. In the Perl case, that's
the viewpoint of the casual user. Once you leave that point, the
different structure of "my" and "our" becomes obvious.

That kind of mental shape-shifting can be bewildering, but it's one of
those things that make Perl what it is.

Anno
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Uri Guttma » Sat, 24 Jul 2004 04:42:36

>>>>> "AS" == Anno Siegel < XXXX@XXXXX.COM > writes:

AS> Uri Guttman < XXXX@XXXXX.COM > wrote in comp.lang.perl.misc:

>> it is much simpler than you realize. it just creates a short nickname in
>> the current lexical or file scope for a package variable. in some ways
>> it is just a lexical version of user 'vars'. so you can do our $foo in
>> two separate files which are in the same package and both $foo's refer
>> to the same package variable. it also means that fully qualified access
>> to $foo is still possible.

AS> It also means that "our" isn't really a declaration, in the sense
AS> that it tells the compiler you are going to use that variable.
AS> Package variables don't need one, the first usage is implicitly
AS> also the declaration. "our" only enables a shortcut. If it
AS> declares anything, it's the lexical alias (which you're not
AS> supposed to know about).

for some definition of 'declaration' :)

AS> In contrast, a lexical variable is actually created by the "my"
AS> statement. The parallelism between "my" and "our" is really bogus
AS> on a deep level, though superficially the rule 'declare lexicals
AS> with "my", package variables with "our"' works well enough.

which was my point. it gets around strict without needing fully
qualified names or use vars which had file scoping.

AS> Two fundamentally different mechanisms work in tandem to let you
AS> deal with package variables just like with lexicals, even under
AS> strict. I liken it with a sculpture where two wildly different
AS> shapes surprisingly show the same profile from one point of view.
AS> In the Perl case, that's the viewpoint of the casual user. Once
AS> you leave that point, the different structure of "my" and "our"
AS> becomes obvious.

but the surface is all that most coders need to know here. so my
description was fine for the poster who never got 'our'. and to make
him feel better it took me a long time to understand it too. it is not
well described in the docs. the whole idea of calling it a lexical
nickname/alias for a package variable is what cleared it up for me.

uri
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by anno400 » Sat, 24 Jul 2004 06:59:01

Uri Guttman < XXXX@XXXXX.COM > wrote in comp.lang.perl.misc:

["my" and "our"]


Oh, sure... I didn't mean to say your explanation was lacking. I
thought it could use some background, for those interested.


Me too, as they, allegedly, say on AOL.


It clears it up, because it explains what is happening in the familiar
terms of lexical variables and their scope, plus the notion of an alias.

That's why I agree, the doc should explain it that way, instead of
beating around the bush with

the same scoping rules as a "my" declaration, but does not cre-
ate a local variable. ...

and

visible across its entire lexical scope, even across package
boundaries. ...

Calling a lexical alias a lexical alias (with a few more words) would
make this and more stuff mere consequences which are to be expected.

Of course, here comes the point where someone gets to mention that
even doc patches speak louder than words.

Anno
 
 
 

`our' declaration causing problems with `strict' pragma across files

Post by Brian McCa » Sun, 25 Jul 2004 04:29:26


XXXX@XXXXX.COM (Anno Siegel) writes:


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\\