Perl 中有一种特殊类型的对象叫 typeglob, 用于处理符号表. perl 中的变量分为两种类型, 一种是 global, 一种是 lexical. perl 中的变量名有个特点, 就是同一个名字可以赋予不同的含义. 比如 $aa, @aa, &aa(子程序 aa) 代表不同对象. perl 内部使用一个全局符号表来存储每个符号名. 每个符号名指向一个被称为 typeglob 的内部结构. 这个结构也是个列表, 保存了所有由该名称定义的 具体特定类型变量的地址 (scalar, list, hash, subroutine, filehandle ...). 在程序中用 *aa 代表名字 aa 所指向的 typeglob.
lexical variable 是通过 my 语句定义的变量. lexical variable 没有被放入 全局符号表, 它被保存在当前子过程(或 block) 的临时存储空间内, 只在该过程内 有效, 是真正的局部变量. 而没有通过 my 声明的全局变量则定义在全局符号表中.
local (gvar) 用于把全局变量 gvar 声明为临时局部化. 执行该语句后, gvar 的全局值被保存, 当过程结束后, 其值自动恢复, 仅此而已. 在 block 中, gvar 使用的仍然是全局符号表中描述的全局变量, 不要被 local 的名字所迷惑.
<> 的功能是从全局变量 @ARGV 中依次读取每个文件的每一行. 所以可以通过 local 临时改变 @ARGV 中的值来使 <> 处理任意文件.
可以对 *aa 进行赋值操作.
*aa = *bb
的功能是令全局符号表中的名字 aa 和 bb 指向同一个 typeglob, 即原先 bb 指向的 typeglob. 也可以对 typeglob 进行 local 操作.
local(*aa)
将全局名字 aa 所指向的 typeglob 暂时保存, 在 block 退出时再自动恢复.
perl 中的引用实际上也是一种特殊的 typeglob. 例如 '\$a' 代表仅保留 a 的标量指针, 其余指针置空的 typeglob, 而 *a 则是 a 的完整 typeglob.
*b = \$a
将仅将 *b 的标量指针修改为 a 的标量指针, *b 的其余指针不动.
内置函数 open 可以用来新定义一个 filehandle,
open (F, "/home/tengfei");
在 *F 中增加一个 filehandle 项. 遗憾的是, 对 filehandle 即不能赋值, 也不能使用 local 操作, 更不能把它作为函数的参数来传递. 同样也不能定义 filehandle 数组. 如果想实现类似功能, 唯一的变通方案 就是通过 typeglob.
*G = *F
让 G 可以作为 filehandle 使用, 且与 F 指向同一个文件. 例如可以通过 如下方式欺骗 print 函数.
local (*STDOUT); *STDOUT = *F; print "hello world\n";
所有需要 filehandle 的 perl 输入输出函数都可以使用 typeglob 作为参数来 调用, 函数内部会自动取出该 typeglob 的 filehandle 部分. (<F> 与 <*F> 等价) open 函数也可使用 string 作为第一个参数. 即下述两个命令等价
open ("F", "/home/tengfei");
open (F, "/home/tengfei");