DarenW
DarenW

Reputation: 16926

Why does strict complain about variables from a required other script?

This is usex.pl:

#use strict;
require 'x.pl';
print $x;

Here is x.pl:

#use strict;
our $x = 99;
1;

It runs fine as shown. If I uncomment the line to use strict in usesx.pl, I get

Global symbol "$x" requires explicit package name

The use or not of strict in x.pl seems not to matter (unless I drop the 'our' keyword, but I'm not interested in that.)

I'm fairly new to Perl. Why does strict make $x not visible in the main script, and what is the normal solution to this?

Upvotes: 0

Views: 283

Answers (2)

ikegami
ikegami

Reputation: 386561

Two reasons.

  1. The error happens at compile-time, before require is ever executed. That's easy to fix using BEGIN.

  2. our is lexically-scoped, and it's in a different lexical scope (file or block) than the print, so it's no longer in effect.

The whole approach is fundamentally bad. Here's one better way:

package MyConfig;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT = qw( $x );
our $x = 123;
1;

use strict;
use warnings;
use MyConfig;
print "$x\n";

Upvotes: 7

Lumi
Lumi

Reputation: 15314

Hehe, our is not easy to grok as it mixes the concepts of global and lexical scope. What it does is exempting a global variable from the strict 'vars' pragma and allowing unqualified access to it within its scope, which is the enclosing block, or the end of the current file, whatever comes first. Read the full (but brief) story in the manual, which is also accessible by saying perldoc -f our on the command line.

As for your script, you can verify the truthfulness of the words in the manual by modifying the variable accessor to use a package-qualified name:

use strict;
require 'x.pl';
print $main::x;

Upvotes: 5

Related Questions