为什么perl警告OpenMy$fh,$文件缺少括号?
这是我学习perl的第一天,我发现这个警告非常令人困惑 在./grep.pl第10行的“我的”列表周围缺少括号 看来为什么perl警告OpenMy$fh,$文件缺少括号?,perl,warnings,suppress-warnings,Perl,Warnings,Suppress Warnings,这是我学习perl的第一天,我发现这个警告非常令人困惑 在./grep.pl第10行的“我的”列表周围缺少括号 看来 open FILE, $file; 很好 你怎么了 open my $fh, $file; 谢谢 #!/usr/bin/perl use strict; use warnings; sub grep_all { my $pattern = shift; while (my $file = shift) {
open FILE, $file;
很好
你怎么了
open my $fh, $file;
谢谢
#!/usr/bin/perl
use strict;
use warnings;
sub grep_all {
my $pattern = shift;
while (my $file = shift) {
open my $fh, $file;
while (my $line = <$fh>) {
if ($line =~ m/$pattern/) {
print $line;
}
}
}
}
grep_all @ARGV;
#/usr/bin/perl
严格使用;
使用警告;
亚格雷普{
我的$pattern=shift;
while(my$file=shift){
打开我的$fh$文件;
while(我的$line=){
如果($line=~m/$pattern/){
打印$行;
}
}
}
}
grep_all@ARGV;
my
用于声明变量或变量列表。在Perl中编写代码是一个常见的错误
my $var1, $var2, $var3;
全部申报。警告应建议您使用正确的格式:
my ($var1, $var2, $var3);
在您的示例中,代码完全符合您的要求(您没有得到任何错误或错误的结果,是吗?),但为了让它绝对清晰,您可以编写
open my ($fh), $file;
尽管有人认为在代码中间放<代码>我的<代码>就像隐藏它。也许更容易阅读:
my $fh;
open $fh, $file;
要获得更详细的警告消息解释,请使用。 比如说,
use strict;
use warnings;
use diagnostics;
my $fh, $file;
将生成以下有用的解释:
“我的”列表中缺少括号
(插入语)你说的是
my $foo, $bar = @_;
when you meant
my ($foo, $bar) = @_;
Remember that "my", "our", and "local" bind tighter than comma.
my $foo, $bar = @_;
您还可以在命令提示符下查看文档:
perldoc -f my
如果列出了多个值,则
列表必须放在括号内
我已经破解Perl超过15年了,我承认这个警告让我抓狂了一分钟,因为标准Perl文档中几乎每个对
open
的示例调用,以及几乎所有现有的Perl教程都包含没有括号的open
,就像您编写的一样
您在使用Perl的第一天就写了这个问题,但是您已经启用了strict
和warnings
pragmata!这是一个很好的开始
错误的开始
“修复”警告的一种简单但愚蠢的方法是禁用所有警告。这将是一个可怕的举动!警告是为了帮助你
压制这一警告的天真方式是放弃旧的方法,转而用一句空话来代替旧的坏方法
open FH, $file;
使用带有open的显式括号
open(my $fh, $file);
使my
的括号显式
open my($fh), $file;
使用外圆括号
(open my $fh, $file);
或者使用3参数
禁用Perl并将$file
视为文件的文字名称非常重要,例如,在处理-use时
解释Perl的警告
Perl的警告在中有进一步的解释,启用将查找Perl发出的任何警告的解释。对于您的代码,输出是
$perl-Mdiagnostics./mygrep模式没有这样的文件
在/mygrep
第10行(#1)的“我的”列表周围缺少括号
(插入语)你说的是
my $foo, $bar = @_;
when you meant
my ($foo, $bar) = @_;
Remember that "my", "our", and "local" bind tighter than comma.
my $foo, $bar = @_;
你什么意思
my ($foo, $bar) = @_;
请记住,my
、our
、local
和state
绑定比逗号更紧
readline()位于关闭的文件句柄$fh
的/mygrep
第11行(#2)
(W closed)您正在读取的文件句柄在以前某个时候关闭了。检查您的控制流
-Mdiagnostics
命令行选项相当于使用诊断代码>在代码中,但按上述方式运行它会暂时启用诊断解释,而无需修改代码本身
警告#2是因为没有这样的文件
不存在,但您的代码无条件地读取$fh
令人费解的是,你竟然看到了警告1!这是我第一次在调用open
时看到它。5.10.1文档中有52个涉及词法文件句柄的open
示例用法,但其中只有两个带有括号的my
它变得越来越古怪:
$ perl -we 'open my $fh, $file'
Name "main::file" used only once: possible typo at -e line 1.
Use of uninitialized value $file in open at -e line 1.
注意第一行的注释。年,马克·多米努斯写道,“当然,这是一种启发式,这是一种说它不起作用的奇特方式。”这种情况下的启发式也不起作用,并产生了令人困惑的警告
有条件的
if (sigil && (*s == ';' || *s == '=')) {
解释为什么perl-我们“打开我的$fh,$file”
不会发出警告,但会使用尾随分号发出警告。注意类似但无意义的代码会发生什么:
$ perl -we 'open my $fh, $file ='
Parentheses missing around "my" list at -e line 1.
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
在这里,警告是有意义的,但您发现的情况是启发式中的漏洞
少就是多
正如文档中所解释的,Perl具有语法上的糖分,使编写变得容易
空文件句柄
非常特殊:它可以用来模拟sed和awk的行为。来自
的输入要么来自标准输入,要么来自命令行上列出的每个文件。它是如何工作的:第一次计算
时,会检查@ARGV
数组,如果它是空的,$ARGV[0]
被设置为“-”
,打开时会提供标准输入。然后将@ARGV
数组作为文件名列表进行处理。环路
while (<>) {
... # code for each line
}
主循环既惯用又紧凑。对于许多Perl运算符来说,$\ucode>特殊变量是默认参数,明智的使用有助于强调实现机制的内容而不是方式
我希望这些建议能有所帮助 真正的问题是忽略函数调用是相当脆弱的。如果你这样做了,你会发现奇怪的错误
$ perl -we'$file="abc"; open(my $fh, $file);'
$ perl -we'$file="abc"; open my $fh, $file;'
Parentheses missing around "my" list at -e line 1.
在我看来,您的代码比需要的要长——您应该使用更多的惰性
#!/usr/bin/env perl
my $pattern = shift;
while (<>)
{
print if m/$pattern/;
}
#/usr/bin/env perl
我的$pattern=shift;
而()
{
如果m/$pattern/,则打印;
}
如果您决定需要行号、文件名(如果有多个文件),或者其他更复杂的打印,那么
if (sigil && (*s == ';' || *s == '=')) {
$ perl -we 'open my $fh, $file ='
Parentheses missing around "my" list at -e line 1.
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
$ perl -lwe 'my $foo, $bar = qw/ baz quux /; print $foo, $bar'
Parentheses missing around "my" list at -e line 1.
Useless use of a constant in void context at -e line 1.
Use of uninitialized value $foo in print at -e line 1.
quux
while (<>) {
... # code for each line
}
unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
open(ARGV, $ARGV);
while (<ARGV>) {
... # code for each line
}
}
$ cat 0
foo
bar
baz
$ ./mygrep bar 0
Parentheses missing around "my" list at ./mygrep line 10.
#! /usr/bin/env perl
use strict;
use warnings;
die "Usage: $0 pattern [file ..]\n" unless @ARGV >= 1;
my $pattern = shift;
my $compiled = eval { qr/$pattern/ };
die "$0: bad pattern ($pattern):\n$@" unless $compiled;
while (<>) {
print if /$compiled/;
}
$ ./mygrep ?foo
./mygrep: bad pattern (?foo):
Quantifier follows nothing in regex; marked by <-- HERE in
m/? <-- HERE foo/ at ./mygrep line 10.
$ perl -we'$file="abc"; open(my $fh, $file);'
$ perl -we'$file="abc"; open my $fh, $file;'
Parentheses missing around "my" list at -e line 1.
#!/usr/bin/env perl
my $pattern = shift;
while (<>)
{
print if m/$pattern/;
}