陈述的答案是,你必须使用local
,因为my *FH
是一个语法错误。
“正确”(但不是非常有启发性)的答案是,你做错了。您应该使用词法文件句柄和open
的三参数形式。
sub newopen {
my $path = shift;
my $fh;
open($fh, '<', $path) or do {
warn "Can't read file '$path' [$!]\n";
return;
}
return $fh;
}
要真正回答为什么需要词汇和全局变量之间的和可变的范围和持续时间之间的差异的解释。
变量的作用域是程序中名称有效的部分。范围是一个静态属性。另一方面,变量的持续时间是一个动态属性。持续时间是指程序执行期间变量存在并保存一个值的时间。
my
声明了一个词法变量。词法变量具有从声明点到封闭块(或文件)结束的范围。您可以在不同范围内使用相同名称的其他变量而不会发生冲突。 (您也可以在重叠范围内重复使用名称,但不这样做。)词汇变量的持续时间通过引用计数进行管理。只要至少有一个对变量的引用存在,即使该名称在特定范围内无效! my
也具有运行时效果 - 它分配新的变量与给定的名称。
local
有点不同。它对全局变量进行操作。全局变量具有全局范围(该名称无处不在)和程序整个生命周期的持续时间。 local
所做的就是临时更改全局变量的值。这有时被称为“动态范围”。更改从local
声明开始,并一直保留到封闭块的结尾,之后旧值被恢复。值得注意的是,新值并不局限于块 - 它随处可见(包括被称为子例程)。引用计数规则仍然适用,因此您可以在更改结束后采取并保留对本地化值的引用。
返回本示例:*FH
是一个全局变量。更准确地说,它是一个“typeglob” - 一组全局变量的容器。一个typeglob包含一个用于每个基本变量类型(标量,数组,散列)以及其他一些事物的槽。历史上,Perl使用typeglobs来存储文件句柄和local
- 它们帮助确保它们不会互相打破。词汇变量没有typeglobs,这就是为什么说my *FH
是语法错误。
在现代版本的Perl词法变量中,可以并应该用作文件句柄。这让我们回到了“正确”的答案。
编程Perl,第三版是很久以前写在远处的一个银河系里的。而且你有一个比这更老的版本! – 2009-09-18 22:43:50
...现在我们到了第6版,我想 – osirisgothra 2014-09-01 16:16:38