如果在另一个名称空间中使用未声明的变量,为什么 Perl 不发出警告 - 我如何收到警告?
Why does Perl not warn if using an undeclared variable in another namespace - and how can I be warned about this?
我在我的 Perl 脚本中使用 strict
和 warning
,以便在我使用未声明的变量时收到通知。因此,解释器将警告 $foo
在以下脚本中未声明:
#!/usr/bin/perl
use warnings;
use strict;
$foo = 'bar';
print ($foo);
但是,如果我在另一个命名空间中使用未声明的变量,则不会收到警告。以下 scriptlet 在没有任何警告的情况下运行。
#!/usr/bin/perl
use warnings;
use strict;
$BAR::foo = 'bar';
print ($BAR::foo);
为什么会有这种差异?
由于我花了很多时间来弄清楚这个问题,尽管是在更大的上下文中,我想知道是否有可能让 Perl 我也警告在其他名称空间中使用未声明的变量。
当您完全指定变量所属的名称空间时,perl
假定您知道自己在做什么。见 perldoc strict
:
strict vars
This generates a compile-time error if you access a variable that was neither explicitly declared (using any of my
, our
, state
, or use vars
) nor fully qualified.
我认为没有办法检测到您指定了一个不存在的变量 $BAR::foo
。但是,如果 BAR
包在你的控制之下,你可以首先避免使用包变量,方法是使用访问器调解对 foo
状态的访问,并对其他模块隐藏该变量。
解决使用全局变量产生的问题的方法是不使用全局变量。
strict vars
This generates a compile-time error if you access a variable that was neither explicitly declared (using any of my
, our
, state
, or use vars
) nor fully qualified.
Perl 在用户使用完全限定的 var 名称时“信任”他们。我怀疑这是为了允许用户在不使用 use strict;
.
的模块中设置配置变量
例如,让我们看看下面使用 Data::Dumper 的片段:
local $Data::Dumper::Useqq = 1;
print(Dumper($s));
即使在引入 use strict;
很久之后,Data::Dumper 也没有声明 $Useqq
。在 use strict;
之前甚至都没有这样做的机制!所以上面的代码片段将使用一个未声明的变量。这意味着如果 strict vars
被强制覆盖完全限定名称,则严格代码将无法以上述方式使用 Data::Dumper。
阻止严格代码使用非严格安全的模块没有意义,因此 strict vars
不涵盖完全限定名称。这些非常罕见且易于识别,足以让程序员在使用它们时更加小心。
I am wondering if it is possible to make Perl me warn about using undeclared variables in other namespaces, too.
我不知道现有的解决方案。或许可以挂接到 Perl 来执行此操作,但这会非常困难。
请记住,如果您只使用一次包变量,Perl 已经警告您,所以这应该可以帮助您发现拼写错误。
我在我的 Perl 脚本中使用 strict
和 warning
,以便在我使用未声明的变量时收到通知。因此,解释器将警告 $foo
在以下脚本中未声明:
#!/usr/bin/perl
use warnings;
use strict;
$foo = 'bar';
print ($foo);
但是,如果我在另一个命名空间中使用未声明的变量,则不会收到警告。以下 scriptlet 在没有任何警告的情况下运行。
#!/usr/bin/perl
use warnings;
use strict;
$BAR::foo = 'bar';
print ($BAR::foo);
为什么会有这种差异?
由于我花了很多时间来弄清楚这个问题,尽管是在更大的上下文中,我想知道是否有可能让 Perl 我也警告在其他名称空间中使用未声明的变量。
当您完全指定变量所属的名称空间时,perl
假定您知道自己在做什么。见 perldoc strict
:
strict vars
This generates a compile-time error if you access a variable that was neither explicitly declared (using any of
my
,our
,state
, oruse vars
) nor fully qualified.
我认为没有办法检测到您指定了一个不存在的变量 $BAR::foo
。但是,如果 BAR
包在你的控制之下,你可以首先避免使用包变量,方法是使用访问器调解对 foo
状态的访问,并对其他模块隐藏该变量。
解决使用全局变量产生的问题的方法是不使用全局变量。
strict vars
This generates a compile-time error if you access a variable that was neither explicitly declared (using any of
my
,our
,state
, oruse vars
) nor fully qualified.
Perl 在用户使用完全限定的 var 名称时“信任”他们。我怀疑这是为了允许用户在不使用 use strict;
.
例如,让我们看看下面使用 Data::Dumper 的片段:
local $Data::Dumper::Useqq = 1;
print(Dumper($s));
即使在引入 use strict;
很久之后,Data::Dumper 也没有声明 $Useqq
。在 use strict;
之前甚至都没有这样做的机制!所以上面的代码片段将使用一个未声明的变量。这意味着如果 strict vars
被强制覆盖完全限定名称,则严格代码将无法以上述方式使用 Data::Dumper。
阻止严格代码使用非严格安全的模块没有意义,因此 strict vars
不涵盖完全限定名称。这些非常罕见且易于识别,足以让程序员在使用它们时更加小心。
I am wondering if it is possible to make Perl me warn about using undeclared variables in other namespaces, too.
我不知道现有的解决方案。或许可以挂接到 Perl 来执行此操作,但这会非常困难。
请记住,如果您只使用一次包变量,Perl 已经警告您,所以这应该可以帮助您发现拼写错误。