我需要用 defined(@array) 和 defined(%hash) 重构一段古老的 Perl 代码

I need to refactor an ancient piece of Perl code with defined(@array) and defined(%hash)

我是 运行 旧版的 Movable Type,对我来说工作得很好。但是,我开始收到以下服务器错误:

defined(@array) is deprecated at /home/public_html/cgi-bin/mt/extlib/Locale/Maketext.pm line 623.
defined(%hash) is deprecated at /home/public_html/cgi-bin/mt/extlib/Locale/Maketext.pm line 623.

我找到了有问题的行:

if defined(%{$module . "::Lexicon"}) or defined(@{$module . "::ISA"});

以下是重构此行的正确方法吗?

if %{$module . "::Lexicon"} or @{$module . "::ISA"};

如果是,为什么?如果不是,为什么不呢?我想更好地了解 defined(@array)defined(%hash).

发生了什么

更新: 我还在 CGI.pm:

的第 367 行发现了类似的问题
if (defined(@QUERY_PARAM) && !defined($initializer)) {

我改写如下,但我仍然不确定它是否正确:

if (@QUERY_PARAM && $initializer) {

我可以看到 @QUERY_PARAM 如何确认它存在,但我可能没有设置 $initializer 存在的第二个条件,我不太确定该怎么做。

$ perl -w -Mdiagnostics -e 'print defined(@array)'

Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at -e
        line 1 (#1)
    (F) defined() is not useful on arrays because it
    checks for an undefined scalar value.  If you want to see if the
    array is empty, just use if (@array) { # not empty } for example.

Uncaught exception from user code:
        Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at -e line 1.

$ [perldoc -f defined](http://metacpan.org/pod/perlfunc#defined)

...

Use of "defined" on aggregates (hashes and arrays) is no longer
supported. It used to report whether memory for that aggregate
had ever been allocated. You should instead use a simple test
for size:

     if (@an_array) { print "has array elements\n" }
     if (%a_hash)   { print "has hash members\n"   }

defined(@array) 构造从来没有完成用户期望它做的事情,而且它实际所做的也没有那么有用,因此它已从语言中删除(并在您使用的 Perl 版本中弃用) .正如诊断和文档所建议的那样,修复它的方法是在布尔上下文中使用 @array 而不是 defined(@array)

正如暴徒所说,解决方案就是if (@array)...if (%hash)...

然而,对于任何好奇的人,您可以检查符号 table 以查看该变量是否曾经自动生成。然而,更多的是,(几乎)没有理由这样做。它只会告诉您您是否是使用该变量的第一行代码。这是 5 个 9 没用。

但是对于第 6 位有效数字,您可以按照以下方法进行操作。我什至知道的唯一用例是在 Carp 中,它检查调用命名空间中的一些变量,而不会在过程中污染它。

这只适用于全局的、非词汇的变量。全局未声明,use vars qw//our()。词汇是 my()state()。符号 table 是包含包中所有全局符号名称的特殊散列。

use Data::Dump qw/pp/;

pp \ %Z::;
{}

$Z::foo = "foo scalar";

pp \ %Z::;
do {
  my $a = { foo => *Z::foo };
  $a->{foo} = \"foo scalar";
  $a;
}

print "symbol exists\n" if exists $Z::{foo};
symbol exists

print "symbol and array exists\n" if $Z::{foo} and defined *{$Z::{foo}}{ARRAY};

pp \ %Z::;
do {
  my $a = { foo => *Z::foo };
  $a->{foo} = \"foo scalar";
  $a;
}

print "symbol and array does not exist\n" unless $Z::{foo} and defined *{$Z::{foo}}{ARRAY};
symbol and array does not exist

pp \ %Z::;
do {
  my $a = { foo => *Z::foo };
  $a->{foo} = \"foo scalar";
  $a;
}