2012年(69)
分类:
2012-10-29 19:27:14
原文地址:perl之glob — 类型团 (函数) 作者:huaius
glob在Perl里有两个意思,一个是数据类型“类型团”(Typeglob),一个是函数。
----------------------------
(一)
Perl 里面有种特殊的类型叫类型团(typeglob)用以保留整个符号表记录。(符号表记录 *foo 包括 $foo, @foo,
%foo,&foo 和其他几个 foo 的简单解释值。)类型团(typeglob)的类型前缀上一个
*,因为它代表所有类型。
类型团(typeglob)(或由此的引用)的一个用途是是用于传递或者存储文件句柄。如果你想保存一个文件句柄,你可以这么干:
$fh = *STDOUT;
或者作为一个真的引用,象这样:
$fh = \*STDOUT;
这也是创建一个本地文件句柄的方法,比如:
参阅 open 函数获取另外一个生成新文件句柄的方法。
类型团如今的主要用途是把一个符号表取另一个符号表名字做别名。别名就是外号,如果你说:
*foo = *bar;
那所有叫“foo”的东西都是每个对应的叫“bar”的同意词。你也可以通过给类型团赋予引用实现只给某一个变量取别名:
*foo = \$bar;
这样 $foo 就是 $bar 的一个别名,而没有把 @foo 做成 @bar 的别名,或者把 %foo 做成 %bar
的别名。所有这些都只影响全局(包)变量;词法不能通过符号表记录访问。象这样给全局变量别名看起来可能有点愚蠢,不过事实是整个模块的输入/输出机制都是建筑在这个特性上的,因为没有人要求你正在当别名用的符号必须在你的名字空间里。因此:
local *Here::blue = \$There::green;
临时为 $There::green 做了一个叫 $Here::blue 的别名,但是不要给 @There:green 做一个叫
@Here::blue 的别名,或者给 %There::green 做一个 %Here::blue
的别名。幸运的是,所有这些复杂的类型团操作都隐藏在你不必关心的地方。参阅第八章的“句柄参考”和“符号表参考”,第十章的“符号表”,和第十一章,模块,看看更多的关于类型团的讨论和重点。
----------------------------
----------------------------
(二)
glob EXPR
glob
这个函数把 EXPR 的值带着 shell 那样的文件名扩展返回。它是实现
<*> 操作符的内部函数。
由于历史原因,这个算法和 csh(1) 的扩展风格相匹配,而不是 Bourne shell 的。早于 5.6 版本的 Perl
使用了一个外部的处理,但 5.6
及以后的版本在内部进行聚团的工作。那些第一个字符是点(“.”)的文件被忽略,除非这个字符是明确匹配的。一个星号(“*”)匹配任意字符的任意序列
(包括空)。一个问号(“?”)匹配任意一个字符。一个方括弧序列(“[
...
]”)声明一个简单的字符表,比如“[chy0-9]”。字符表可以用音调符号取反,象“*.[^oa]”,它匹配任意非点文件,这些文件的文件名博爱喊
一个点,后面跟着一个字符在文件名尾部,但这个字符既不能是“a”也不能是“o”。一个波浪号(“~”)扩展成一个家目录,象“~/.*rc”是指当前用
户的所有
“rc”文件,或者“~jane/Mail/*”似乎所有 Jane
的邮件文件。花括弧可以用于候补,象在“!/.{mail,ex,csh,twm,}rc”里面的是获取那些特定的 rc 文件。
如果你想聚集那些可能包含空白的文件名,你可能需要直接使用 File::Glob 模块,因为老祖父 glob
把空白用于分隔多个模式,比如 <*.c
*.h>。更多细节,请参阅第三十二章的 File::Glob。调用 glob (或者
<*> 操作符)自动 use
该模块,因此如果该模块莫名其妙地从你的库里消失了,那么就会抛出一个例外。
当你调用 open 的时候,Perl 并不扩展通配符,包括波浪号。你需要先把结果 glob 起来。
glob 函数和 Perl 的类型团的概念没有任何关系,只不过它们都用 * 代表多个项。
----------------------------
参考资料:Perl语言编程(第三版)