使用严格的空列表相当于不使用严格吗?

时间:2016-11-03 12:20:03

标签: perl

TLDR:请参阅问题标题。

original version of a question中,程序顶部有use strict ();。没有使用my声明变量。该计划奏效了。我指出,由于缺少my s,代码无效,但事实证明我错了。

$ perl e 'use strict (); $foo = 1'

这个程序有效。它没有崩溃。但很明显这会崩溃:

$ perl -e 'use strict; $foo = 1'
Global symbol "$foo" requires explicit package name (did you forget to declare "my $foo"?) at -e line 1.
Execution of -e aborted due to compilation errors.

我的第一个想法是将其解析,看看是否还有其他事情发生。

$ perl -MO=Deparse -e 'use strict (); $foo = 1'
use strict ();
$foo = 1;
-e syntax OK

但事实并非如此。然后它让我思考,你可以做use strict 'vars'打开vars thing 1 。显然,通过调用import来做到这一点。

use strictBEGIN { require strict; strict->import; }相同,因此模块的相同规则也应适用于pragmata。如果我use Foo (),则不会导入任何内容。因此,use strict ();应该与require strict;相同,只是在运行时,因为没有导入任何内容。

$ perl -e 'require strict; $foo = 1'

这不会崩溃。但是在运行时,你无法打开应该在编译时设置的东西。

那实际上是做什么的?当Perl到达我的实际代码时,它可能已经在其他地方遇到了strict pragma,因此它不会再次加载它。而且它不会导入任何东西。

$ perl -e 'print %INC'

糟糕。这没什么打印。 %INC是空的。但是如果我们使用另一个模块,那么它就会有一些东西。

$ perl -MData::Dumper -e 'print Dumper \%INC'
$VAR1 = {
          'warnings.pm' => '/usr/share/perl/5.22/warnings.pm',
          'overload.pm' => '/usr/share/perl/5.22/overload.pm',
          'Carp.pm' => '/usr/share/perl/5.22/Carp.pm',
          'strict.pm' => '/usr/share/perl/5.22/strict.pm',
          'overloading.pm' => '/usr/share/perl/5.22/overloading.pm',
          'constant.pm' => '/usr/share/perl/5.22/constant.pm',
          'bytes.pm' => '/usr/share/perl/5.22/bytes.pm',
          'Data/Dumper.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.22/Data/Dumper.pm',
          'XSLoader.pm' => '/usr/share/perl/5.22/XSLoader.pm',
          'Exporter.pm' => '/usr/share/perl/5.22/Exporter.pm',
          'warnings/register.pm' => '/usr/share/perl/5.22/warnings/register.pm'
        };

如果我们加载Data :: Dumper,则会在某个时刻加载strict。但不是纯粹的-e示例。

$ perl -e 'use strict (); print %INC'
strict.pm/usr/share/perl/5.22/strict.pm

确定。这会加载strict.pm。

$ perl -e 'require strict; print %INC'
strict.pm/usr/share/perl/5.22/strict.pm

那样做。但是,strict事件都没有启用。

所以问题确实是,use strict ()等同于根本没有use strict声明,或者是否还有其他事情发生?

1)perldoc strict指的是strict可以作为事物

的三个不同论点

1 个答案:

答案 0 :(得分:4)

use strict ();

(基本上)没有做任何事情:见the docs

  

如果您不想调用包的导入方法(例如,为了阻止您的命名空间被更改),请显式提供空列表:

     

use Module ();

     

这完全等同于

     

BEGIN { require Module }

当然,strict只会在调用import方法时执行某些操作(您可以通过阅读其源代码轻松验证它;它只有大约150行长)。因此绕过import方法会绕过use strict的整个效果。