1.将数据和函数包装到单独的命名空间中称为封装(encapsulation)(C++程序员称之为类(class),面向对象的perl程序员称之为类)。独胆的命名空间又称之为包(package)。单独的命名空间意味着:对于命名包中的所有变量,perl都持有一个单独的符号表。

2.符号表:在编译程序时,编译器必须记录使用的所有变量名、文件句柄、目录句柄、格式和子函数。perl将这些符号的名称作为键存储在每个包的散列表中。散列的名称与包名相同。与散列键相关联的值是对应的typeglob值,又称为别名(aliase)。typeglob会“glob”所有可用符号名称表达的类型。对于用相同名称表示的每个值,perl实际上会创建单独的内部指针。如下:

 

每个包都有它自己的符号表。无论何时使用包生命,都要切换到该包的符号表。

用户可通过双冒号(::)用包名限定某个由local函数赋值的变量,从而实现在另一个包中访问该变量。此时该变量仍在作用域中,并可从主机符号表中访问它。

由my函数赋值的变量将不能从其所在包的外面访问。他们并没有存储在包符号表中,而是存储在每个调用子函数创建的专用缓冲区里。因此,在使用“my”创建变量时,用户将无法通过包的符号表来访问他们,因为他们根本不在那里。

 

[root@dou shili]# cat p1.pl

#!/usr/bin/perl -w
use strict;

our (@friends, @dogs, $key, $value);

my($name,$money);
$name="susan";
@friends=qw(tom jack);
@dogs=qw(china usa);
local $main::dou="hello";
$money="dollar";
while(($key,$value) = each(%main::)) {
        print "$key:\t$value\n";
}
[root@dou shili]# perl p1.pl
Name "main::dou" used only once: possible typo at p1.pl line 9.
/:      *main::/
stderr: *main::stderr
friends:        *main::friends
key:    *main::key
utf8::: *main::utf8::
":      *main::"
CORE::: *main::CORE::
DynaLoader:::   *main::DynaLoader::
strict:::       *main::strict::
stdout: *main::stdout
attributes:::   *main::attributes::
:       *main::
stdin:  *main::stdin
ARGV:   *main::ARGV
value:  *main::value
INC:    *main::INC
ENV:    *main::ENV
Regexp:::       *main::Regexp::
UNIVERSAL:::    *main::UNIVERSAL::
$:      *main::$
_<perlio.c:     *main::_<perlio.c
dou:    *main::dou
main::: *main::main::
Carp::: *main::Carp::
-:      *main::-
_<perlmain.c:   *main::_<perlmain.c
PerlIO:::       *main::PerlIO::
_<universal.c:  *main::_<universal.c
0:      *main::0
BEGIN:  *main::BEGIN                                                                     :*main::
@:      *main::@
_<xsutils.c:    *main::_<xsutils.c
STDOUT: *main::STDOUT
IO:::   *main::IO::
:       *main::
_:      *main::_
+:      *main::+
STDERR: *main::STDERR
Internals:::    *main::Internals::
STDIN:  *main::STDIN
DB:::   *main::DB::
<none>:::       *main::<none>::
dogs:   *main::dogs