Perl - 编码规范
每个程序员当然会有自己对格式化的偏好,但有一些通用准则可以让你的程序更容易阅读、理解和维护。
最重要的是始终在程序下使用 -w 标志运行。你可以在特定代码段中通过 no warnings pragma 或 $^W 变量显式关闭它,如果你必须这么做。你还应该始终使用 use strict,或者知道为什么不使用。use sigtrap 甚至 use diagnostics pragma 也可能很有用。
关于代码布局的美观,Larry 唯一强烈关心的就是多行 BLOCK 的结束大括号应该与启动该结构的关键词对齐。除此之外,他还有其他不那么强烈的偏好——
- 4 列缩进。
- 如果可能,开括号与关键词在同一行,否则对齐。
- 多行
BLOCK的开括号前加空格。 - 单行
BLOCK可以放在一行上,包括大括号。 - 分号前无空格。
- “短”单行
BLOCK中省略分号。 - 大多数运算符周围加空格。
- “复杂”下标(括号内)周围加空格。
- 不同功能的代码块之间加空行。
- 不紧挨的
else。 - 函数名与其开括号之间无空格。
- 每个逗号后加空格。
- 长行在运算符后换行(
and和or除外)。 - 当前行最后一个匹配的右括号后加空格。
- 垂直对齐对应项。
- 只要清晰度不受影响,省略多余的标点。
这里还有一些更实质性的风格问题需要考虑:仅仅因为你能以某种方式做某事,并不意味着你应该那样做。Perl 被设计为提供多种方式来完成任何事情,因此考虑选择最易读的方式。例如——
open(FOO,$foo) || die "Can't open $foo: $!";
比以下更好——
die "Can't open $foo: $!" unless open(FOO,$foo);
因为第二种方式将语句的主要点隐藏在修饰语中。另一方面,
print "Starting analysis\n" if $verbose;
比以下更好——
$verbose && print "Starting analysis\n";
因为主要点不是用户是否输入了 -v。
不要为了在循环顶部或底部退出而进行无谓的扭曲,当 Perl 提供了 last 运算符让你可以在中间退出。只需稍微“减少缩进”使其更明显——
LINE:
for (;;) {
statements;
last LINE if $foo;
next LINE if /^#/;
statements;
}
让我们看看更多重要点——
不要害怕使用循环标签——它们的存在是为了提高可读性以及允许多级循环中断。请参阅前面的示例。
避免在 void 上下文中使用
grep()(或map())或`backticks`,即当你只是丢弃它们的返回值时。这些函数都有返回值,所以要使用它们。否则,使用foreach()循环或system()函数。为了可移植性,当使用可能并非在每台机器上都实现的特性时,在
eval中测试该结构以查看是否失败。如果你知道特定特性是在哪个版本或 patchlevel 实现的,你可以测试$](英文中的$PERL_VERSION)来查看它是否存在。Config模块还可以让你查询 Perl 安装时由Configure程序确定的值。选择助记符标识符。如果你不记得助记符是什么意思,你就有问题了。
虽然像
$gotit这样的短标识符可能没问题,但请在较长的标识符中使用下划线分隔单词。阅读$var_names_like_this通常比$VarNamesLikeThis更容易,尤其是对非英语母语者来说。这也是一个简单且与VAR_NAMES_LIKE_THIS一致的规则。包名有时是此规则的例外。Perl 非正式地将小写模块名保留给像
integer和strict这样的“pragma”模块。其他模块应以大写字母开头并使用混合大小写,但由于原始文件系统对模块名作为文件的表示限制(必须适应少数稀疏字节),可能不使用下划线。如果你的正则表达式非常复杂,请使用
/x修饰符并添加一些空白使其看起来不那么像行噪声。当你的 regexp 包含斜杠或反斜杠时,不要使用斜杠作为分隔符。始终检查系统调用的返回码。好的错误消息应发送到 STDERR,包括导致问题的程序、失败的系统调用及其参数是什么,以及(非常重要)包含标准系统错误消息说明出了什么问题。这里是一个简单但足够的示例——
opendir(D, $dir) or die "can't opendir $dir: $!";
考虑可重用性。为什么要为一次性任务浪费脑力,而你可能以后还会做类似的事情?考虑将你的代码泛化。考虑编写模块或 object class。考虑让你的代码在
use strict和use warnings(或-w)生效时干净运行。考虑分享你的代码。考虑改变你的整个世界观。考虑……哦,算了。保持一致。
友善待人。