【问题标题】:Find data point generating Error in Perl code在 Perl 代码中查找生成错误的数据点
【发布时间】:2015-04-15 05:03:10
【问题描述】:

我有一个 Perl 程序,它一次从数据文件中读取一行,并为每一行数据计算某些统计信息。时不时地,当程序读取我的数据集时,我会收到关于 ...uninitialized value... 的警告,我想知道哪一行数据会生成此警告。 有什么方法可以告诉 Perl 打印(到屏幕或归档)产生错误的数据点?

【问题讨论】:

    标签: perl variables runtime-error warnings


    【解决方案1】:

    如果您的脚本为每个输入行打印一行,则通过将标准错误与输出一起刷新(使消息出现在“正确”点)来查看错误发生的时间会更简单:

    $| = 1;
    

    即开启perl autoflush功能,如How to flush output to the console?中所讨论

    (自动)刷新的作用:

    • 错误消息写入预定义的 STDERR 流,正常 printf 转到(默认)预定义的 STDOUT。
    • 写入这些流的数据由系统保存(在 Perl 的控制下),以块(称为“缓冲区”)的形式写入,以提高效率。
    • STDERR 和 STDOUT 缓冲区是独立的,可以逐行或按缓冲区写入(许多字符,不一定是行)。
    • 使用 autoflush 告诉 Perl 修改其写入缓冲区的方案,以便在 print/printf 调用结束时通过操作系统写入其内容。
    • 通常 STDERR 是逐行写入的。该命令告诉 Perl 为当前/默认流启用此功能,即 STDOUT。
    • 这样做会使它们都逐行写入,以便及时发送close的消息在脚本的输出中一起显示close

    【讨论】:

    • 为了回答您的问题,我的代码读取一行值,计算某些统计数据并将它们写入输出文件;然后从数据文件中取出下一行,读取它等等。我对“刷新”对我的代码所做的事情有点困惑:它应该将错误消息添加到我的输出文件还是应该打印程序读取数据文件时导致屏幕错误的数据行?
    • 我从你的回答中学到了很多;我现在将尝试在我的代码中实现它!
    【解决方案2】:

    默认情况下,Perl 通常在警告中包含文件句柄和行号;即

    >echo hello | perl -lnwe 'print $x'
    Name "main::x" used only once: possible typo at -e line 1.
    Use of uninitialized value $x in print at -e line 1, <> line 1.
    

    因此,如果您在阅读时进行计算,则会收到相应的警告。

    【讨论】:

    • 但是,这不是告诉我代码中的行吗?我想知道数据集中哪一行产生了错误...
    • 它应该告诉你两个。请注意我的代码产生了 2 个警告。第一次发生在编译时,所以它只给出了脚本中的行(-e)。第二个给出了脚本(-e 第 1 行)和文件句柄( 第 1 行),因为它发生在 打开并被读取时。
    • 我还没有弄清楚为什么,就我而言,Perl 只告诉我代码行而不是数据集中产生错误的那一行:您有什么想法/建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2017-12-19
    • 2023-04-05
    • 1970-01-01
    • 2013-03-23
    • 2022-08-16
    • 2016-06-30
    相关资源
    最近更新 更多