perl常问问题集--第七篇
目录
篇名
概述
我能拿到 Perl的 BNF/yacc/RE吗?
$@%*这些符号是什麽意思?我怎麽知道何时该使用他们呢?
字串加引号或使用分号及逗号是否绝对必要/还是完全没必要?
我如何跳过一些传回值?
我如何暂时滤掉警告讯息?
什麽是一个扩充 (extension)?
为何 Perl运算子的优先顺序和 C的不一样?
我如何宣告/生成一个资料结构 (structure)?
我如何创造出一个模组 (module)?
我如何创造一个类别 (class)?
我如何辨别一个变数是否被污染了(tainted)?
闭包 (closure)是啥?
何谓变数自杀而我又该如何防止它?
我如何传递/传回一个 {函数,档案把手,阵列,杂凑阵列,方法,和正规表现式}?
我如何生成一个静态变数?
动态与文字式(静态)范围界定 (scoping)有何不同? Local()和 my()呢?
当同一个范围中有一个文字式变数时,我该如何去撷取同名的动态变数?
所谓深连结与浅连结 (deep and shallow binding)间有何不同呢?
为何 "local($foo) = ;"无法正确地作用?
我如何重新定义一个内建函数、运算子或是方法?
用 &foo和 foo()的方式来呼叫一个函数有什麽不同?
我如何作一个 switch或 case叙述?
我如何抓到呼叫未定义变数/函数/方法的事件?
为什麽我的程式会找不到放在同一档案中的方法 (method)呢?
我如何找出目前所在的 package为何?
我如何将一大块 perl程式码变成注解?
作者与版权事宜
--------------------------------------------------------------------------------
篇名
perlfaq7 - Perl语言相关问题 ($(原文版 Revision: 1.18, Date: 1997/04/24 22:44:14 中译版 $Revision: 1.1 $ $Date: 1998/01/16 23:57:56 $)
--------------------------------------------------------------------------------
概述
本篇内的问题主要是不适合纳入其他篇章的一般性 Perl语言问题。
--------------------------------------------------------------------------------
我能拿到 Perl的 BNF/yacc/RE吗?
不行,引用 Chaim Frenkel的话:“Perl的语法无法被简化到可以用 BNF 表示。解析Perl的工作是分散於 yacc、lexer、烟雾和镜子之间。”
--------------------------------------------------------------------------------
$@%*这些符号是什麽意思?我怎麽知道何时该使用他们呢?
他们都是指定形态 (type)用的符号,如同 perldata里所详述的:
$纯量值 (scalar) (数字,字串或参考值 [reference])
@阵列
%杂凑阵列 (关连阵列)
*代表同一个变数名的所有类形。在第四版中它们常用来达到指标
(pointers)的功能,但现在在新版的 perl中这个角色已被参
考值 (reference)取代了。
虽然这些符号在某些场合下可省略,但建议你随处都用。
有些其他的符号你可能会碰到但却不是指定形态用的有:
<>这是用来从一个档案把手 (filehandle)里输入一份记录
\取某样东西的参考值 (reference)
注意 < FILE> 不是用来指定档案的形态,亦非此把手的名字。它只是 将<>这个运算子用在 FILE这个把手上。在纯量的情境 (scalar context) 下,它自 FILE 把手一次读入一行 (嗯,该说一笔记录,参看 $/),在序列情境 (list context)下,则一次将 全部的内容读 入。当对档案使用开、关或其它 <>之外的动作、或甚至只是提到把 手时,切记不要使用 <>。下面的用法是正确的:eof(FH) , seek(FH, 0,2) 以及 ``copying from STDIN to FILE''。
--------------------------------------------------------------------------------
字串加引号或使用分号及逗号是否绝对必要/还是完全没必要?
通常一个没有冠上形态符号的字 (bareword)是不需被纳入引号里的,但在大多数 的情况下或许该这麽做 (在use strict下则是必须的)。但由一个简单的字(不 能是一个已定义的副函数之名称)所构成的索引值,和 =>左端的运算子,都会被视为已纳入引号了:
这些是和这些一样的
------------ ---------------
$foo{line} $foo{"line"}
bar => stuff "bar" => stuff
一个区块末端的分号可有可无,一个序列的最後一个逗号亦同。良好的写作风格 (参看perlstyle)中建议除了在单行程式 (one-liners)的情况外都将他们加上去:
if ($whoops) { exit 1 }
@nums = (1, 2, 3);
if ($whoops) {
exit 1;
}
@lines = (
"There Beren came from mountains cold",
"And lost he wandered under leaves",
);
--------------------------------------------------------------------------------
我如何跳过一些传回值?
一种方法是将传回值当作序列来对待,然後用索引来指名其中的某个位置:
$dir = (getpwnam($user))[7];
另一种方法就是在等号左端用 undef 作元素:
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
--------------------------------------------------------------------------------
我如何暂时滤掉警告讯息?
$^W变数 (在 perlvar中有说明)控制一个区块在执行期 (runtime)的警告讯息:
{
local $^W = 0; #暂时关掉警告讯息
$a = $b + $c; #我知道这些变数可能未定义
}
注意,像所有的标点符号变数一样,目前不能对 $^W用 my,只能用 local()。
一个发展中的新 use warnings编译器指挥模组 (pragma) 提供了更精细的控制。好奇宝宝们应该翻翻 perl5-porters 邮件论坛的档案库以获得更详细的说明。
--------------------------------------------------------------------------------
什麽是一个扩充 (extension)?
一种从 Perl呼叫编译好的 C程式码的方法。阅读 perlxstut是个多了解扩充(extensions)的好方法。
--------------------------------------------------------------------------------
为何 Perl运算子的优先顺序和 C的不一样?
事实上它们是相同的。所有 Perl自 C借过来的运算子都具备与原来在 C 中相同的优先顺序。问题出在那些 C没有的运算子,特别是那些将其右方一律当成序列情境对待的函数,例如 print, chmod, exec等等。这类的函数被称作“序列运算子”(list operators),在 perlop的优先顺序表中就是这麽称呼。
一个常犯的错误像是:
unlink $file || die "snafu";
这会被解译器看成是:
unlink ($file || die "snafu");
要避免此问题,须加上括号或是用超低优先的 or运算子:
(unlink $file) || die "snafu";
unlink $file or die "snafu";
这些“英文的”运算子 (and, or, xor,及 not)是刻意设计成较一般序列运算子低的优先顺序,这就是为了解决前述的状况。
另一个拥有出人意料的优先顺序者为指数。它甚至高
Tags:perl,常问,问题,第七

