Perl 范围与格式/写入的混淆



如果$var的范围几乎是包级的,为什么当用my声明时write不可用(超出范围?)?

package ASDF;
use warnings;
use strict;
use feature 'say';
my $var = 'foo';
format =
@<<<<< @>>>>>
'test : ', $var
.

sub test {
say $var;
write;
}

1;

调用 :

perl -wE 'use ASDF; ASDF::test();'

生产:

foo
Variable "$var" is not available at ASDF.pm line 16.
Use of uninitialized value $var in formline at ASDF.pm line 10.
test :

它似乎可供同一范围内的say使用......

my替换为our修复它:

foo
test :    foo

为什么write不能正确拾取$var
这是一个范围问题,还是Perl的writeformat如何实现的问题?

在Perl格式文档的底部,它说:

法变量(用"my"声明)在格式中不可见,除非格式是在词法变量范围内声明的。

阅读这将意味着您正在尝试的内容将起作用,但显然词法范围的变量在从声明的包外部调用时,formatwrite的工作方式不同。此外,本文中的所有示例都使用全局变量...

这个关于格式的更现代的教程重复了如果您使用词法范围的变量(用my声明的变量)可能会遇到麻烦,因为 write 从当前包中挑选变量,并且如您的问题评论中所述,是在 Perl 没有my关键字或词法范围的时候编写的。

本文提供的解决方案:

当您准备好输出一些数据时,您可以使用写入。此设计显示了格式的年龄,因为写入不需要参数来填充图片。它使用范围内的变量。

our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();

格式也有点粗糙,因为您不会传递要编写的参数来填充图片。Perl 依赖于指定名称在范围内的变量。可以使用词法变量,但它们必须与格式定义位于同一范围内,并且在调用 write 时必须位于作用域中。使用词法这样做是不切实际的,因此最敏捷的方式涉及本地化的包变量:

foreach my $record ( @cats ) {
local( $id, $name, $food ) = @$record;
write( $fh );
}

还有总结中的这个建议:

  • 使用本地化的包变量设置格式的数据

所以,如果你想在现代Perl中继续使用formatwriteourlocal似乎是你要走的路。

最新更新