Perl 我的语言的词汇范围

Perl 我的语言的词汇范围,perl,Perl,几乎所有编写的perl程序都使用以下习惯用法: { open(my $fh, '>>', $filename) || die "you lose"; print $fh $blah; } 然而,我不想死,我只想跳过打印。 所以我写: { print "you lose\n" unless (open(my $fh, '>>', $filename) and print $fh $blah); } 并获取“不能在./o.pl第5行使用未定义的值作为符号引用”以解决我的问

几乎所有编写的perl程序都使用以下习惯用法:

{
open(my $fh, '>>', $filename) || die "you lose";
print $fh $blah;
}
然而,我不想死,我只想跳过打印。 所以我写:

{
print "you lose\n" unless (open(my $fh, '>>', $filename) and print $fh $blah);
}
并获取“不能在./o.pl第5行使用未定义的值作为符号引用”以解决我的问题

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

{
my $fh;
print "you lose\n" unless (open($fh, '>>', $filename) and print $fh $blah);
}
但是为什么呢


为什么在断开的代码中,
$fh
打开(my$fh…
到块的关闭(the
}
)不存在?

直到语句结束,
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";
这张照片是:

inside, x = 43
outside, x = 42

您的
open
语句大致相当于上面的内部
my
语句。如果您在外部范围中声明了
$fh
,则会出现令人惊讶的乐趣:您可能最终打印到错误的文件。

您不能声明词法变量并在同一语句中使用它

不管你怎么做

open($_, '>>', $filename) and print $_ $blah for my $fh;


如果将
strict
warnings
添加到程序中,您将得到更多有用的错误消息:

use strict;
use warnings;

{
   my $filename = "test.txt";
   print "you lose\n" unless (open(my $fh, '>>', $filename) 
         and print {$fh} $blah);
}

__END__
Global symbol "$fh" requires explicit package name at test.pl line 6.
Global symbol "$blah" requires explicit package name at test.pl line 6.
Execution of test.pl aborted due to compilation errors.
问题在于不能在同一语句中声明和使用词法变量。
$fh
仅在其上有
打开的
行之后可用。

您可能更喜欢

{
  open(my $fh, '>>', $filename) || warn "you lose";
  print $fh $blah if $fh->opened;
}
当然,如果您愿意,也可以删除
警告

如果您的Perl5比版本14旧,则需要添加

use IO::File

谢谢你的清晰解释。PS,在我看来,perl在这里失败的主要原因是“最少的意外”。如果你希望最少的意外(或至少通知意外),“几乎所有编写的perl程序都使用这个习惯用法”哦,如果那是真的就好了!是和否;新词汇是“return”可以使用my和so。不能在同一语句中按名称引用词法。这是有意义的。只有在语句执行后,名称才会添加到该范围的符号表中,对吗?不,它是在编译时添加的,但仅限于特定的语句范围。
use IO::File