我的词汇范围

Joh*_*all 5 perl

几乎每个编写的perl程序都使用这个成语:

{
open(my $fh, '>>', $filename) || die "you lose";
print $fh $blah;
}
Run Code Online (Sandbox Code Playgroud)

但是,我不想死,我想跳过打印.所以我写道:

{
print "you lose\n" unless (open(my $fh, '>>', $filename) and print $fh $blah);
}
Run Code Online (Sandbox Code Playgroud)

为了我的麻烦,得到"不能使用未定义的值作为./o.pl第5行的符号引用".

删除my(错误表单)可以消除此错误,如下所示:

{
my $fh;
print "you lose\n" unless (open($fh, '>>', $filename) and print $fh $blah);
}
Run Code Online (Sandbox Code Playgroud)

但为什么?

为什么,在破碎的代码中,$fhopen(my $fh...块(the })的结尾不存在?

Joe*_*e Z 10

my不会生效,直至语句结束.

出于同样的原因,my $x = $x不会$x在声明的右侧看到新的.它会看到旧的$x.

例如

use strict;
use warnings;

my $x = 42;

{
    my $x = $x + 1;
    print "inside, x = $x\n";
}

print "outside, x = $x\n";
Run Code Online (Sandbox Code Playgroud)

这打印:

inside, x = 43
outside, x = 42
Run Code Online (Sandbox Code Playgroud)

您的open陈述大致相当于my上面的内部陈述.如果您已$fh在外部范围内声明,则会发生令人惊讶的乐趣:您可能最终打印到错误的文件.

  • 如果你想要最少的惊喜(或至少通知惊喜),启用严格和警告 (3认同)

Bor*_*din 5

你可能更喜欢

{
  open(my $fh, '>>', $filename) || warn "you lose";
  print $fh $blah if $fh->opened;
}
Run Code Online (Sandbox Code Playgroud)

当然,warn如果您愿意,也可以删除.

如果您的Perl 5早于版本14,则需要添加

use IO::File
Run Code Online (Sandbox Code Playgroud)

到代码的标题.