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 strict
与BEGIN { 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
可以作为事物
答案 0 :(得分:4)
use strict ();
(基本上)没有做任何事情:见the docs:
如果您不想调用包的导入方法(例如,为了阻止您的命名空间被更改),请显式提供空列表:
use Module ();
这完全等同于
BEGIN { require Module }
当然,strict
只会在调用import
方法时执行某些操作(您可以通过阅读其源代码轻松验证它;它只有大约150行长)。因此绕过import
方法会绕过use strict
的整个效果。