views:

605

answers:

4

I have a question relating to Perl and scoping. I have a common file with lots of various variables. I require the common file in my main script, but I cannot access the variables; they seem to be outside of its scope. I assumed that an our declaration would overcome that problem, but it doesn't seem to work.

Script 1: common.pl

#!/usr/bin/perl

our $var1 = "something";
our $var2 = "somethingelse";

Script 2: ftp.pl

#!/usr/bin/perl

use strict;
use warnings;

require('common.pl');

print $var1;

I get the error:

Global symbol "$var1" requires explicit package name

+7  A: 

There's no require statement in your second example, but it wouldn't work anyway. What our does is declare a lexically-scoped package variable. Since you have no package statement, it uses the default package main. So your first script sets up the variable $main::var1, but this will only be available within that file's scope.

A better way to provide common variables for other scripts is to use Exporter. You can define package symbols in one place and Exporter will take care of copying them to the requesting script or class's namespace when needed.

friedo
+5  A: 

It looks like you need a proper configuration file there. I'd go for a non-code configuration file that you can read when you need to setup things. There are modules on CPAN to handle just about any configuration format you can imagine.

If you want to do it the way you have it, get rid of our and declare them with use vars. Don't let the PBP police scare you off that. :) You only really need our to limit a scope of a package variable, and that's exactly the opposite of what you are trying to do.

brian d foy
Well using strict won't allow me to not use a variable definition such as our or my.
Lee
A problem exists that i am working on perl versions that can not be modified.. e.g. no new modules.
Lee
If you can add perl files you can use all pure perl modules, it's just a bit fiddly since you have to take care of dependencies yourself. Just download the source of the module you want and put it where "your" perlscript can read it.
Nifle
No new modules? What do you think you're doing? :)
brian d foy
+5  A: 

I would put the config in a module instead.

File: MyConfig.pm

package MyConfig;
require Exporter;
use strict;

our @ISA                = qw(Exporter);
our @EXPORT             = qw( getconfig ); 

my %confighash = ( 
            thisone => 'one',
            thatone => 2,
            somthingelse => 'froboz',
          );



sub getconfig {
 return  %confighash;
 }

1;

Example usage:

#!/usr/bin/perl
use strict;
use warnings;

use MyConfig;

my %config = getconfig();

print $config{ somthingelse };

This should print froboz

Nifle
+2  A: 

our() does something a little different than you think. Its sole purpose is to work with strict in requiring you to declare package variables that you are going to use (unless they are fully-qualified or imported). Like strict, its effect is lexically-scoped. To use it to allow accessing a global $main:var1 from multiple files (which are separate scopes) as just $var1, you need to say our $var1 in each file.

Alternatively, you would change your required file to be a module with its own package that exports the variables to any package that uses it.

ysth