2016-11-03 48 views
10

TLDR:查看問題標題。是否嚴格使用等於完全不使用嚴格的空列表?

original version of a question中,程序頂部有use strict();my沒有聲明變量。該計劃奏效。我指出,由於缺少my,代碼將不起作用,但事實證明我錯了。

$ 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. 

我的第一個想法是要deparse它,看看是否有其他事情正在進行。

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

但事實並非如此。然後它讓我想到,你可以做use strict 'vars',其中只有打開增值經銷商東西 。很明顯,通過撥打import

use strictBEGIN { require strict; strict->import; }相同,因此模塊的相同規則也應適用於註釋。如果我做use Foo(),則不會導入任何東西。因此,use strict();應該與運行時的require strict;相同,因爲沒有任何內容被導入。

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

這不會崩潰。但是在運行時你不能打開應該在編譯時設置的東西。

那麼這到底是什麼呢?當Perl達到我的實際代碼時,它可能已經在其他地方遇到strict編譯指示,因此它不會再次加載它。它不會導入任何東西。

$ 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

[使用strict();'和類似的](http://grep.cpan.me/?q=use+strict%5Cs*%5C%28%5C%29)的CPAN給了我們一個幾擊。雖然[HTTP :: PAI](https://metacpan.org/pod/HTTP::OAI)[聲明](https://metacpan.org/source/TIMBRODY/HTTP-OAI-4.03/CHANGES#L59)至做到這一點,實際的代碼只有'use strict;'。雖然有三種分佈明確不會從'嚴格'中導入任何內容。 – simbabque

回答

4
use strict(); 

(基本上)不會做任何事情:看the docs

如果你不想調用包的導入方法(例如,要停止你的命名空間被修改),明確地提供一個空列表:

use Module();

這是完全等同於

BEGIN { require Module }

當然,strict只有當你調用它的import方法(做一些東西,您可以通過閱讀其源代碼輕鬆進行驗證;它只有大約150行)。因此繞過import方法繞過use strict的整個效果。