【问题标题】:Why are use warnings; use strict; not default in Perl?为什么要使用警告;使用严格;在 Perl 中不是默认的?
【发布时间】:2011-08-28 08:19:26
【问题描述】:

我想知道为什么

use warnings;
use strict;

在 Perl 中不是默认的。每个脚本都需要它们。如果有人(出于充分的理由)需要禁用它们,他们应该使用 no strict 和/或应该使用一些命令行参数(对于单行)。

是否有太多写得不好的 CPAN 模块(用“badly”表示没有use strict)?还是因为这会破坏已经在生产中的大量代码?我确定这是有原因的,我很想知道。

在 5.14 中,IO::File 会按需自动加载,难道不能用这些基本的 pragma 做类似的事情吗?

【问题讨论】:

标签: perl


【解决方案1】:

warningsstrict 最终都将成为默认值(以及一些不是默认值的 Perl 5 功能)with Perl 7。预计将于 2021 年上半年发布(可能会在 2020 年底左右发布候选版本)。也许它会在 5 月 18 日左右发布,以纪念这个问题的 10 周年?迟到总比没有好!

【讨论】:

    【解决方案2】:

    这是一个哲学问题,而不是“行不通”的问题。

    首先,perl 一直处于“如果你愿意,你可以做错”的范式。这就是为什么有很多反对 perl 的人。许多人更喜欢这种语言总是强迫你编写好的代码,但许多快速脚本黑客不想这样做。考虑:

    perl -e '@a = split(/[,:]/, $_); print $a[1],"\n";'
    

    现在,在 @a 前面添加“我的”很容易,但对于单行一次性脚本,人们不想这样做。

    第二,是的,我认为大部分 CPAN 确实需要重写。

    恐怕没有一个你会喜欢的好答案。

    【讨论】:

    • 为什么单行需要$_
    • 好点:不是。这不是最短的方法,但它是人们最容易理解的。从技术上讲,您也不需要@a,也可以直接从拆分输出中打印。但我试图减少混淆。
    【解决方案3】:

    这是为了向后兼容。 Perl 4 根本没有严格,而且很可能仍然有最初为 Perl 4 编写的脚本仍然可以在 Perl 5 中正常工作。使严格自动会破坏这些脚本。单行代码的情况更糟,其中许多都懒得声明变量。默认情况下严格设置单行代码可能会破坏数百万个 shell 脚本和 Makefile。

    它不能自动加载,因为它增加了限制,而不是特性。在文件句柄上调用方法时加载 IO::File 是一回事。但是除非代码做了严格禁止的事情,否则激活严格是没有意义的。

    如果脚本指定最低版本为 5.11.0 或更高版本(例如use 5.012),则为strict is turned on automatically。这不会启用警告,但可能会在未来的版本中添加。另外,如果您在 Perl 中进行 OO 编程,您应该知道使用 Moose 会自动打开该类中的 strictwarnings

    【讨论】:

    • Perl 4 中有很多东西在 Perl 5 中被破坏了,比如作为包说明符的记号。别介意它无法指定strict;它根本没有词法变量范围,因此在 Perl 4 中工作的脚本不可能在严格的 Perl 5 中也工作。主要问题是在没有 strict 的情况下编写的 Perl 5 脚本记住,尤其是那些单行字。
    • @MarkReed,作为包说明符的记号在 Perl 5 中仍然有效;他们只是不推荐(例如Acme::Don't)。 AFAIK,大多数 Perl 4 代码在 Perl 5 中工作(只要你不尝试use strict)。
    • 好吧,我会被吓到的。 perl -MText::CSV -E "say Text'CSV->new" 产生 Text::CSV=HASH(0x7fe1b982ccb0)。直到。谢谢!
    【解决方案4】:

    如果需要,您可以使用common::sense 模块:

    使用utf8;
    使用严格的 qw(vars subs);
    使用功能 qw(比如状态开关);
    没有警告;
    使用警告 qw(致命关闭线程内部调试包
                    便携式原型就地 io 管道解压 malloc
                    不推荐使用 glob digit printf 层
                    保留污点关闭分号);
    没有警告 qw(exec newline unopened);

    它减少了内存使用量。

    【讨论】:

    • 不幸的是,common::sense 不是很常识。没有应默认关闭的警告或限制。
    • common::sense 不是。它选择的警告和限制它无法打开反映了作者的怪癖,而不是好的做法。特别是,未能打开严格的引用和未定义的警告是自找麻烦。至于内存使用声明,虽然严格正确,但在实践中从未见过。一旦加载了任何其他明智的模块,就会加载严格和警告。在实践中,你最终会使用更多的内存。最后,作者不是您想要联系以寻求支持的人。
    • @Schwern:它也忘记打开unicode_strings。一个明确的警告列表意味着你可能忘记了一些未来不存在的警告,比如包警告。最后,您必须将致命错误延迟到运行时,否则编译器会在错误报告时出现错误行为。
    【解决方案5】:

    嗯,use strict 现在是默认设置了。

    从 Perl 5.12.0 开始,如果您需要 Perl >= 5.12.0 的版本,那么您的脚本将启用所有向后不兼容的功能,包括默认情况下的严格。

    use 5.12.0;
    use warnings;
    

    等同于:

    use strict;
    use warnings;
    use feature ':5.12';
    

    尚未更广泛地启用它,因为这样做会破坏许多人们依赖于“正常工作”的脚本。

    Moose 还会在您使用时自动开启严格和警告。因此,如果您执行任何基于 Moose 的 Perl OOP,那么您也可以在这里获得免费通行证。

    【讨论】:

      【解决方案6】:

      如果您使用的是现代 Perl,那么您只需启用它即可。 5.12 applies strict except for one-liners.向后兼容,不能默认。

      $ cat strict-safe?.pl
      use 5.012;
      $foo
      
      $ perl strict-safe\?.pl 
      Global symbol "$foo" requires explicit package name at strict-safe?.pl line 2.
      Execution of strict-safe?.pl aborted due to compilation errors.
      

      【讨论】:

        猜你喜欢
        • 2013-08-06
        • 2020-04-09
        • 2012-12-27
        • 2010-09-16
        • 2011-09-19
        • 2017-04-26
        • 2011-07-22
        • 2016-09-16
        相关资源
        最近更新 更多