首页 > 解决方案 > Perl 抱怨全局符号需要明确的包名,尽管严格和警告已关闭

问题描述

use utf8;
use v5.14.0;
@rocks = qw/ bedrock slate rubble granite /;
while( ( $index, $value ) = each @rocks ) {
    say "$index: $value\n";
}

输出:

C:\Users\J\Documents\Development\perl>perl test.pl
Global symbol "@rocks" requires explicit package name at test.pl line 6.
Global symbol "$index" requires explicit package name at test.pl line 7.
Global symbol "$value" requires explicit package name at test.pl line 7.
Global symbol "@rocks" requires explicit package name at test.pl line 7.
Global symbol "$index" requires explicit package name at test.pl line 8.
Global symbol "$value" requires explicit package name at test.pl line 8.
Execution of test.pl aborted due to compilation errors.

我读过不包括使用严格和使用警告可以规避这个问题。但是我已经删除了严格和警告,就在这里。我知道不使用严格是非常危险的,但我只是在玩代码。不得不打字

my @rocks = qw/ bedrock slate rubble granite /;
while( (my $index, my $value ) = each @rocks ) {
    say "$index: $value\n";
}

当你只是在玩的时候有点烦人。

看起来

use v5.14.0;

正在开启严格或警告;真的吗?如果是这样,怎么会?如果是这样,我如何才能使用say而不必在每个 sodding 变量前面加上$my?如果我的文件中没有该行,我似乎无法使用 say use v5.14.0.;

标签: perl

解决方案


似乎use v5.14.0;正在打开严格或警告;真的吗?如果是这样,怎么会?

不幸的是,这方面的文档use隐藏在.

使用 VERSION 还按词汇启用由功能编译指示定义的请求版本中可用的所有功能,禁用不在请求版本的功能包中的任何功能。见功能。类似地,如果指定的 Perl 版本大于或等于 5.12.0,则在词法上启用严格,就像使用严格一样。任何显式使用 use strict 或没有严格覆盖都使用 VERSION ,即使它出现在它之前。以后使用 use VERSION 将覆盖以前使用 VERSION 的所有行为,可能会删除 use VERSION 添加的严格和功能。使用 VERSION 不会加载 feature.pm 或 strict.pm 文件。

如果是这样,我如何才能使用 say 而不必在每个 sodding 变量前面加上 $my?

您可以使用 单独加载功能use feature。所以use feature "say"。您还可以使用use v5.10.

但是你真的,真的,真的要严格要求。真的真的真的。显式声明变量my为您提供了两个重要功能:错字保护和词法范围。错字保护是显而易见的,如果你打字$receiver = 42,然后print $reciever你可能会花很多时间挠头,直到你意识到你有错字。这足以弥补打字所花费的时间my

同样重要的是词法作用域。这意味着变量只存在于它声明的块内。

use strict;

sub foo {
    my $thing = 42;
}

print $thing;  # error

默认情况下,没有my变量是全局的。任何地方的任何一段代码都可以随时接触到一个全局变量。这使得除了最小的代码片段之外的所有代码都变得更加复杂和难以理解,并将它们变成了噩梦,供以后必须维护它的人使用。您还冒着意外将同一个变量用于两个不同目的的风险,尤其是使用像$countor这样的通用名称$i,神秘地覆盖彼此的值。


推荐阅读