为什么perl警告OpenMy$fh,$文件缺少括号?

为什么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) {

这是我学习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 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/;
}