TLDR:查看问题标题.
在问题的原始版本中,有一个use strict ();位于程序的顶部.没有声明变量my.该计划奏效了.我指出,由于缺少mys,代码不起作用,但事实证明我错了.
$ perl e 'use strict (); $foo = 1'
Run Code Online (Sandbox Code Playgroud)
这个程序有效.它没有崩溃.但显然这崩溃了:
$ 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.
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是将其解析,看看是否还有其他事情发生.
$ perl -MO=Deparse -e 'use strict (); $foo = 1'
use strict ();
$foo = 1;
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.然后它让我思考,你可以做use strict 'vars',只能打开vars的事情1.它显然通过调用来做到这一点import.
它use strict是相同的BEGIN { require strict; strict->import; },因此模块的相同规则也应该适用于pragmata.如果我这样做use Foo (),则不会导入任何内容 因此,use strict ();应该与require strict;运行时相同,因为没有导入任何内容.
$ perl -e 'require strict; $foo = 1'
Run Code Online (Sandbox Code Playgroud)
这不会崩溃.但是在运行时你无法打开应该在编译时设置的东西.
那么这实际上是做什么的呢?当Perl到达我的实际代码时,它可能已经在strict其他地方遇到了pragma,因此它不会再次加载它.而且它不会导入任何东西.
$ perl -e 'print %INC'
Run Code Online (Sandbox Code Playgroud)
哎呀.这没什么打印.%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'
};
Run Code Online (Sandbox Code Playgroud)
如果我们加载Data :: Dumper,strict则在某些时候加载.但不是纯粹的-e例子.
$ perl -e 'use strict (); print %INC'
strict.pm/usr/share/perl/5.22/strict.pm
Run Code Online (Sandbox Code Playgroud)
好.这会加载strict.pm.
$ perl -e 'require strict; print %INC'
strict.pm/usr/share/perl/5.22/strict.pm
Run Code Online (Sandbox Code Playgroud)
那样做.但是,仍然没有strict启用任何东西.
所以问题确实是,use strict ()等同于根本没有use strict声明,或者是否还有其他事情发生?
1)perldoc strict指的是三个不同的参数strict可以作为事物
use strict ();
Run Code Online (Sandbox Code Playgroud)
(本质上)不做任何事情:请参阅文档:
如果您不想调用包的导入方法(例如,为了阻止名称空间被更改),请显式提供空列表:
use Module ();这完全相当于
BEGIN { require Module }
当然,strict只有在调用它的import方法时才会执行某些操作(您可以通过阅读其源代码轻松验证;它只有大约 150 行长)。因此绕过该import方法就绕过了 的整个效果use strict。