全局变量在模块(module)和包(package)中的共享
    创建全局变量

当你第一次在代码中写下$x的时候你就创建了一个全局变量。它在你使用的文件的任何地方可见。如果它是定义在一个包中,那么它就在这个包的内部是可见的,但是在mod_perl下运行你的代码,你必须要使用strict参数才能实现上面所述。

    打开strict参数,创建全局变量

首先使用:
use strict;
然后使用:
    use vars qw($scalar %hash @array);
这时这些变量在其被定义的包中成为全局变量,如果你想在包与包之间共享全局变量的话,我们要在下面来实现。

    使用Exporter.pm来共享全局变量

假设你想在模块之间共享CGI.pm的一个对象(在这里我用$q表示)。我们在script.pl创建这个对象,但是却像是它在My:HTML中可见,首先把$q设为全局变量。
script.pl:
  ----------------
  use vars qw($q);
  use CGI;
  use lib qw(.); 
  use My::HTML qw($q); # My/HTML.pm in the same dir as script.pl
  $q = new CGI;
  
  My::HTML::printmyheader();
  ----------------

注意,我们从My::HTML引入$q,并且My::HTML做了$q的输出工作。

My/HTML.pm
  ----------------
  package My::HTML;
  use strict;
  
  BEGIN {
    use Exporter ();
  
    @My::HTML::ISA         = qw(Exporter);
    @My::HTML::EXPORT      = qw();
    @My::HTML::EXPORT_OK   = qw($q);
  
  }
  
  use vars qw($q);
  
  sub printmyheader{
    # Whatever you want to do with $q... e.g.
    print $q->header();
  }
  1;
  -------------------

这样$q被在My::HTML包和script.pl程序间共享。反之亦然,如果你在My::HTML中创建对象而在script.pl中使用,也可共享。你所实现的是真正意义的共享,因为如果你在script.pl中改变了$q变量的话,在My::HTML中它也被同时改变了。
要是想在多于两个包中共享$q,应该怎么办呢?下面的例子是你还想在My::Doc中共享$q对象:
不必改变My::HTML包,修改script.pl加入:

use My::Doc qw($q);

然后,按照My::HTML的格式创建My::Doc模块——当然它们的内容是不同的。
如果你想在My::HTML中和script.pl中都使用My::Doc的话,必须还要在My::HTML中加入:
use My::Doc qw($q);
$q才会被共享。否则My::Doc不再共享$q。下面的代码给予了更清晰的说明:
script.pl:
  ----------------
  use vars qw($q);
  use CGI;
  use lib qw(.); 
  use My::HTML qw($q); # My/HTML.pm in the same dir as script.pl
  use My::Doc  qw($q); # Ditto
  $q = new CGI;
  
  My::HTML::printmyheader();
  ----------------
  My/HTML.pm
  ----------------
  package My::HTML;
  use strict;
  
  BEGIN {
    use Exporter ();
  
    @My::HTML::ISA         = qw(Exporter);
    @My::HTML::EXPORT      = qw();
    @My::HTML::EXPORT_OK   = qw($q);
  
  }
  
  use vars     qw($q);
  use My::Doc  qw($q);
  
  sub printmyheader{
    # Whatever you want to do with $q... e.g.
    print $q->header();
  
    My::Doc::printtitle('Guide');
  }
  1;
  -------------------
  My/Doc.pm
  ----------------
  package My::Doc;
  use strict;
  
  BEGIN {
    use Exporter ();
  
    @My::Doc::ISA         = qw(Exporter);
    @My::Doc::EXPORT      = qw();
    @My::Doc::EXPORT_OK   = qw($q);
  
  }
  
  use vars qw($q);
  
  sub printtitle{
    my $title = shift || 'None';
    
    print $q->h1($title);
  }
  1;
  -------------------

    使用变量别名来共享全局变量

像题目所说的,你可以不使用Exporter.pm就能把变量引入脚本或模块中。我发现把所有的配置变量保存在一个模块My::Config中非常有用,但是在其它模块中使用的时候我又不得不把它们全部输出。这样有两点不好之处:多余的标记会“污染”其它模块的命名空间,还会导致内存需求的增加。系统开销会加大,因为要保存对从配置模块输出变量及向其它模块的输入变量。我解决这个问题的方法是把这些所有的变量保存到一个哈系数组%c中。这有一个My::Config模块的例子:
package My::Config;
  use strict;
  use vars qw(%c);
  %c = (
    # All the configs go here
    scalar_var => 5,
  
    array_var  => [
                   foo,
                   bar,
                  ],
  
    hash_var   => {
                   foo => 'Foo',
                   bar => 'BARRR',
                  },
  );
  1;
现在在包中要使用配置变量,我只要用它的全名就可以了,如$My::Config::test。那么现在既然只有一个变量需要处理,事情就变得简单多了,也可以省去载入Exporter.pm包的开销。我们可以使用Perl的别名特性(aliasing)来进行变量的输出,也可以省去总要敲一大串键盘。
package My::HTML;
  use strict;
  use lib qw(.);
    # Global Configuration now aliased to global %c
  use My::Config (); # My/Config.pm in the same dir as script.pl
  use vars qw(%c);
  *c = \%My::Config::c;
  
    # Now you can access the variables from the My::Config
  print $c{scalar_val};
  print $c{array_val}[0];
print $c{hash_val}{foo};

当然,你以上述方法描述的$c是在各处可见的全局变量,如果你在某处改变它的值,则会影响到你在其它模块中定义的My::Config::c的变量别名。
注意,别名仅在全局或是以local()定义的变量中有效,你不能这样写:
my *c=\%My::Config::c;
那是错误的,但是你可以这样写:
local *c=\%My::Config::c;