我需要用 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;
}
我是 运行 旧版的 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
:
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;
}