这是我第一天来perl,我觉得这个警告很混乱.

Parentheses missing around “my” list at ./grep.pl line 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;

解决方法

我一直在黑客攻击Perl已经15年了,我承认这个警告让我刮伤了我一分钟,因为几乎每一个例子都要打开标准的Perl文档,几乎每一个Perl教程都是开放的,没有括号就像你写的一样.

您在第一天使用Perl写了这个问题,但是您已经启用了严格和警告pragmata!这是一个很好的开始.

假启动

一个简单而愚蠢的方法来“修复”警告是禁用所有警告.这将是一个可怕的举动!警告是为了帮助你.

无奈的镇压警告的方式是放弃了lexical filehandle,以赤字为借口

open FH,$file;

使用明确的括号打开

open(my $fh,$file);

使我的括号明确

open my($fh),$file;

使用外接括号

(open my $fh,$file);

或使用3参数open.

open my $fh,"<",$file;

我建议不要使用任何这些,因为它们都有严重的遗漏.

最好的方法

一般来说,沉默这个关于缺失括号的警告的最佳方法包括不添加括号!

始终检查是否打开成功,例如,

open my $fh,$file or die "$0: open $file: $!";

要禁用Perl的magic open并将$file视为文件的文字名称,在处理untrusted user input使用时

open my $fh,$file or die "$0: open $file: $!";

是的,两者都封闭了警告,但是更重要的好处是您的程序处理不可避免的错误,而不是忽视它们,并且无论如何还是向前收费.

继续阅读以了解为什么你收到警告,有助于您提供下一个Perl程序,一些Perl理念,并建议您改进代码.最后,你会看到你的程序不需要显式调用打开!

写有用的错误信息

注意传递给die的错误信息的重要组成部分:

>抱怨的程序($0)
>它试图做什么(“打开$文件”)
>为什么它失败($!)

这些特殊变量在perlvar中有记录.现在就要将每个错误信息中包含这些重要信息的习惯现在开发出来 – 尽管不一定是用户看到的.拥有所有这些重要信息将在未来节省调试时间.

始终检查是否打开成功!

再次,始终检查打开和其他系统调用是否成功!否则,最终会出现奇怪的错误:

$./mygrep pattern no-such-file
Parentheses missing around "my" list at ./mygrep line 10.
readline() on closed filehandle $fh at ./mygrep line 11.

Perl的警告说明

在perldiag documentation,Perl的警告有进一步的解释,diagnostics pragma将会查看perl发出的任何警告的解释.使用你的代码,输出是

$perl -Mdiagnostics ./mygrep pattern no-such-file
Parentheses missing around “my” list at ./mygrep line 10 (#1)
(W parenthesis) You said something like

06008

when you meant

06009

Remember that my,our,local and state bind tighter than comma.

readline() on closed filehandle $fh at ./mygrep line 11 (#2)
(W closed) The filehandle you’re reading from got itself closed sometime before Now. Check your control flow.

-Mdiagnostics命令行选项等效于使用诊断;在您的代码中,但如上所述运行它可临时启用诊断说明,而无需修改代码本身.

警告#2是因为没有这样的文件不存在,但你的代码无条件地从$fh读取.

令人困惑的是,你看到1号警告!这是我第一次记得看到它与打开的电话相关联. 5.10.1文档有52个例子用于涉及词法文件句柄,但只有两个与我的括号相同.

它好奇好奇:

$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.

括号丢失,那么警告在哪里?

然而,添加一个小分号警告失踪括号:

$perl -we 'open my $fh,$file;'
Parentheses missing around "my" list at -e line 1.
Name "main::file" used only once: possible typo at -e line 1.
Use of uninitialized value $file in open at -e line 1.

我们来看看perl的来源,看看警告来自哪里.

$grep -rl 'Parentheses missing' .
./t/lib/warnings/op
./op.c
./pod/perl561delta.pod
./pod/perldiag.pod
./pod/perl56delta.pod

Perl_localize in op.c–处理我的,我们的,状态的和本地的 – 包含以下代码段:

/* some heuristics to detect a potential error */
while (*s && (strchr(",\t\n",*s)))
  s++;

while (1) {
  if (*s && strchr("@$%*",*s) && *++s
       && (isALNUM(*s) || UTF8_IS_CONTINUED(*s))) {
    s++;
    sigil = TRUE;
    while (*s && (isALNUM(*s) || UTF8_IS_CONTINUED(*s)))
      s++;
    while (*s && (strchr(",*s)))
      s++;
  }
  else
    break;
}
if (sigil && (*s == ';' || *s == '=')) {
  Perl_warner(aTHX_ packWARN(WARN_PARENTHESIS),"Parentheses missing around \"%s\" list",lex
      ? (PL_parser->in_my == KEY_our
        ? "our"
        : PL_parser->in_my == KEY_state
          ? "state"
          : "my")
      : "local");
}

注意第一行的注释.在My Life With Spam年,Mark Dominus写道:“当然,这是一种启发式的方式,这是一种说法不起作用的花哨的方法.”在这种情况下,启发式方法也不起作用,产生混乱的警告.

有条件的

if (sigil && (*s == ';' || *s == '=')) {

解释为什么perl -we’打开我的$fh,$文件’不警告,但是使用后缀分号.看看会发生什么类似但荒谬的代码:

$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.

我们得到警告! 3参数的开放案例不会发生警告,因为“<”防止sigil变成真实的,或者是... ...修饰符以钝的方式通过,因为或者令牌以除了以外的字符开始;或=. 警告的目的似乎是提供一个有用的提示,如何修复代码,否则会产生令人惊讶的结果,

$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

在这里,警告确实有意义,但是您发现的情况是启发式漏洞.

少即是多

如perlop文档中所述,Perl具有使写Unix-style filters容易的语法糖.

The null filehandle <> is special: it can be used to emulate the behavior of sed and awk. Input from <> comes either from standard input,or from each file listed on the command line. Here’s how it works: the first time <> is evaluated,the @ARGV array is checked,and if it is empty,$ARGV[0] is set to "-",which when opened gives you standard input. The @ARGV array is then processed as a list of filenames. The loop

060017

is equivalent to the following Perl-like pseudo code:

060018

使用空文件句柄(也称为钻石操作符)使您的代码的行为像Unix grep实用程序.

>过滤命令行上命名的每个文件的每一行,或
>只给出一个模式,过滤标准输入的每一行

钻石运算符还处理至少一个您的代码没有的角落.在下面的注释中,该栏存在于输入中,但不出现在输出中.

$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/;
}

而不是硬编码perl的路径,使用env来尊重用户的PATH.

不要盲目地假设用户至少在命令行上提供了一个模式,检查它是否存在或提供有用的使用指南.

因为你的模式生活在一个变量中,它可能会改变.这不是很深刻,但这意味着每次代码评估/ $pattern /,即每行输入时,都可能需要重新编译该模式.使用qr//避免了这种浪费,并且还提供了一个机会来检查用户在命令行中提供的模式是否是有效的正则表达式.

$./mygrep ?foo
./mygrep: bad pattern (?foo):
Quantifier follows nothing in regex; marked by <-- HERE in
m/? <-- HERE foo/ at ./mygrep line 10.

主循环既成语又紧凑. $_特殊变量是许多Perl运算符的默认参数,明智的使用有助于强调实现的机制,而不是如何实现.

我希望这些建议有所帮助!

为什么perl警告打开我的$fh,$文件缺少括号?的更多相关文章

  1. ios – 如何识别显示为空括号的空NSData对象?

    我正在处理GameKit的GKTurnBasedMatch类中的损坏问题(参见thisthread),这有时会导致游戏状态无效,matchData损坏.因此,作为一种解决方法,我正在创建一种方法来识别这些无效匹配,以便我可以适当地处理它们.损坏的matchData似乎是一种很好的方法.但是,到目前为止,我一直无法识别它们.当我这样做:我得到以下内容:所以匹配数据显示为一对空括号“”,我希望可以

  2. Swift快速入门五集合

    相关文章Swift快速入门(一)第一个Swift程序Swift快速入门(二)基本数据类型Swift快速入门(三)运算符Swift快速入门(四)流程控制前言Swift提供了数组和字典两种集合类型来存储数据,Swift的数组用来存储顺序相同类型相同的类型,字典则采用kay-value的形式存储数据。修改字典字典提供了updataValue()方法来修改字典的value值,该方法会返回一个Sting?

  3. 减少Swift中的括号数

    有人知道有没有办法使用某种速记的速记?

  4. javascript中的括号()用法小结

    ()作为一个数学运算中的基本符号,在计算机程序中也被大量使用,最基本的就是提高运算优先级,JS中也不例外

  5. JS方法调用括号的问题探讨

    JS方法调用括号的问题很是令人头疼,下面有个不错的示例,感兴趣的朋友可以参考下

  6. 解读python正则表达式括号问题

    这篇文章主要介绍了python正则表达式括号问题解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. AngularJS 中括号的作用详解

    这篇文章主要介绍了AngularJS 中括号的作用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. PHP判断表达式中括号是否匹配的简单实例

    下面小编就为大家带来一篇PHP判断表达式中括号是否匹配的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. PHP与Perl之间知识点区别整理

    在本篇文章里小编给大家分享了关于PHP与Perl的却别以及相关知识点整理,有兴趣的朋友们学习下。

  10. 尝试在Windows 7上安装MinGW和Tk for Perl

    我一直试图让这个工作几个星期了.我可以通过.exe安装MinGW,但不管我做什么我似乎无法获得支持或ppm安装MinGW以这样的方式工作,以便我的编译Tk-804.029将正确使用’make’命令.(安装Perl模块:>perlMakeFile.PL–工作正常>make或dmake–我无法让MinGW正确关联Make或DMake(在MinGW/bin目录中找不到正确的.exe…我尝试过使用-32bitmingw32-make.exe但是这会导致与编译的头文件有关的错误.)ppm安装MinGW也不行,似乎觉

随机推荐

  1. 数组 – Perl中有什么神奇的数组?

    在Perldocumentationforreverse中,我发现:“请注意,将数组反转到自身(如@a=reverse@a)将尽可能保留不存在的元素;即对于非魔法数组或具有EXISTS和DELETE方法的绑定数组.什么属性区分神奇和非魔法阵列?解决方法一个神奇的阵列是一个执行它的操作不仅仅是改变内容.只有内置的魔术阵列是@ISA,而且这是非常不明显的.正如句子所暗示的,魔术阵列主要是一个绑定的阵列

  2. perl – 使用“isa”方法的最佳方式?

    什么是“最好的”使用方式“isa()”可靠?解决方法Scalar::Util实现明确更好.它避免了eval{}的开销,它总是导致设置一个附加变量.Scalar::Util实现更容易阅读.如果eval也失败了,我相信发生的是你在树之前向后走到eval之前的状态–这是如何实现复位状态.这带来了额外的故障开销.基准根本不是一个对象对象传递isa检查对象出现故障现象检查测试代码:我使用这是为i486-linux-gnu-thread-multi建立的perl,v5.10.1(*),以及Scalar::Util,1

  3. 在CORE :: GLOBAL中哪些Perl内置函数不能被覆盖?

    解决方法toke.c中任何值为负的值都可以被覆盖;所有其他人可能不会.你可以看源码here.例如,我们来看看第10,396行的waitpid:由于waitpid为负数,因此可能会被覆盖.grep怎么样?这是积极的,所以不能被覆盖.这意味着以下关键字不能被覆盖:chop,defined,delete,do,dump,each,else,elsif,eval,exists,for,foreach,format,glob,goto,grep,if,keys,last,local,m,map,my,next,no

  4. 如何在Perl中打印由换行符分隔的列表元素?

    什么是最简单的打印所有列表的元素以Perl中的换行符分隔的元素?解决方法在Perl5.10中:其他方式:或:或者怎么样?

  5. 使用Perl如何获取文件大小(以兆字节为单位)?

    我想以磁盘的形式获取磁盘上的文件大小.使用-s运算符给出了以字节为单位的大小,但是我将假设,然后将其除以魔术数字是一个坏主意:我应该使用只读变量来定义1024,还是有一种编程方式来获取一千字节的字节数?

  6. perl – 如何测试/分类CPAN模块的utf8正确性

    例如:File::Slurp,如果你将读取该文件您将根据命令行开关获得不同的结果,并且perl-CSDA将无法正常工作.伤心.(是的,我知道比Encode::decode(“utf8”,read_file($file,binmode=>’:raw’));将帮助,但是SAD.我的问题:>在这里任何首选方式,如何测试/分类什么CPAN模块是utf8安全/准备/正确?>这里是像Perl::Criticforutf8这样的东西–什么将检查模块源可能的utf8不正确?总结以上是DEVMAX为你收集整理的perl–如

  7. 如何删除Perl字符串中的空格?

    如果我声明一个值为’3’的变量$myString.是否有任何功能来删除返回值的空格.有点像SomeFun然后返回’3′.输出:你可以注意到’vid’=>‘0’,上面的代码从theanswer.我正在研究它.总结以上是DEVMAX为你收集整理的如何删除Perl字符串中的空格?如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

  8. 如何在mod_perl2下运行Devel :: Cover?

    Unfortunately,Devel::Coverdoesnotyetworkwiththreads.它也不适用于prefork.在startup.pl中使用,Devel::Cover问题perl5.8.9,Apache2.2.13.我的操作系统是FreeBSD,如果重要.同样的问题是reportedforwin32.更新:PerlTrace全部输出解决方法邪恶之源似乎是Apache::DBI.

  9. 如何使用Perl中的C类?

    我有一套用C写的课.从Perl脚本中调用它们的最佳方法是什么?

  10. perl – 在Emacs中以双模式更好的缩进

    我正在使用Emacs来修改Perl和Verilog交织的代码.我正在使用two-mode-mode在两者之间切换,这样可以预期.问题是perl代码与//一行一行地表示;如下图所示:而双模式则认识到它是Perl,它是逐行的,所以缩进等在线上无意义.我想做的是使Perl代码像往常一样格式化,但忽略//;字符.有什么想法吗?我刚刚开始偷看模式文件,它们是可以理解的复杂的,所以任何提示都不会感激!

返回
顶部