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



我正在运行一个古老版本的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 elementsn" }
if (%a_hash)   { print "has hash membersn"   }

defined(@array)构造从来没有做过用户期望它做的事情,而且它实际做的事情也没有那么有用,所以它被从语言中删除了(在您使用的Perl版本中也不推荐使用(。正如诊断和文档所建议的那样,修复它的方法是在布尔上下文中只使用@array而不是defined(@array)

正如mob所说,解决方案只是执行if (@array)...if (%hash)...

然而,对于任何好奇的人来说,你可以检查符号表,看看这个变量是否已经被自动激活了。然而,更重要的是,(几乎(没有理由这样做。它只会告诉你,如果你是使用该变量的第一行代码。这是5个9的无用。

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

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

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 existsn" if exists $Z::{foo};
symbol exists
print "symbol and array existsn" 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 existn" 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;
}


最新更新