Variables (not just in Perl, but in pretty much every programming language) have something called a scope. This is an area of the program where that variable is "visible". Accessing a variable from outside its scope is impossible in normal circumstances, and often generates a warning or error.
{ # braces open and close scopes
my $variable = "value\n";
# This works, because $variable is visible.
print $variable;
}
# This doesn't work, because we've left the scope
# where $variable was originally declared.
# Under "use strict" it will generate an error
# message. Without "use strict", it will fail
# silently.
print $variable;
The granddaddy of all scopes is the file scope. If a lexical variable (one declared using my) is declared outside of any braces, then its scope is the file itself. This means that the variables you declared in your example are invisible outside def_variables.pl.
To cross file scopes, you need to use global variables - that is, variables which have a scope of "the entire program". Apart from a few pre-defined variables (like $_ and %ENV - see perlvar for a full list), global variables in Perl are always namespace-qualified. In other words, they always have names which include "::". For example:
- $main::foo
- @Web::Server::ISA
Because typing out namespace-qualified variable names is annoying, Perl offers a shortcut to take a namespace-qualified global variable, and start using it as if it were a lexical variable.
{
package Web::Server;
# Within this scope, we can use @ISA as a
# shortcut for @Web::Server::ISA
our @ISA = ('Server');
}
package by the way, is how Perl determines what namespace we're currently in. If you don't explicitly say which package to use, the default is main.
Getting back to your example, here's a rewritten def_variable.pl:
package MyConfig;
our $inputdir = "/cygsrive/d/acec/CDRe/data/input/$swname";
our $arbordir = "/cygsrive/d/acec/CDRe/data/output/ARBOR/$swname";
our $arborcsvdir = "/cygsrive/d/acec/CDRe/data/output/ARBORCSV/$swnam
+e";
our $fmsdir = "/cygsrive/d/acec/CDRe/data/output/FMS/$swname";
our $inbilldir = "/cygsrive/d/acec/CDRe/data/output/INBILL/$swname"
+;
our $errordir = "/cygsrive/d/acec/CDRe/data/error/$swname";
our $filterdir = "/cygsrive/d/acec/CDRe/data/filter/$swname";
our $archivedir = "/cygsrive/d/acec/CDRe/data/archive/$swname";
our $duplicatedir = "/cygsrive/d/acec/CDRe/data/duplicate/$swname";
our $baddir = "/cygsrive/d/acec/CDRe/data/bad/$swname";
And here's a rewritten main.pl:
#!/usr/bin/perl
require "./def_variable.pl";
print "INPUT : $MyConfig::inputdir\n";
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
|