我刚刚找到了一个我们正在使用的脚本,其中有一个子my %INC
,其中存储了一些关于激励的值,因此%INC
。这似乎永远不会成为一个问题,或者没有人注意到。对我来说,它产生了20个重新定义的重新警告屏幕,因为%INC
包含所有文件名Perl do
ne,require
d或use
d,非常大,并且现在是('stuff' => 123)
。
我是否真的必须在sub中重命名每一个引用,或者是否有另一种方法让Perl原谅这个......?
以下是输出的一部分:
print Dumper \%INC; # I added this line
my %INC;
print Dumper \%INC; # I added this line
exit; # I added this line
输出:
[...]
'SqlConnect.pm' => 'lib1/SqlConnect.pm',
'Lib/RateRequest.pm' => 'Lib/RateRequest.pm'
};
$VAR1 = {};
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine export_fail redefined at /usr/lib/perl5/5.14.2/Carp.pm line 43.
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine _cgc redefined at /usr/lib/perl5/5.14.2/Carp.pm line 45.
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine longmess redefined at /usr/lib/perl5/5.14.2/Carp.pm line 51.
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine shortmess redefined at /usr/lib/perl5/5.14.2/Carp.pm line 71.
[...] (Snipped like 20 screens of redefine warnings)
警告只显示我是否创建了一个类的对象(恰好包含SOAP::WSDL
,因此它中有很多东西)。我不确定为什么这些是重新定义的警告。如果%INC
为空,那怎么知道正在重新定义的东西?
更新
您实际上可以创建词汇my %INC
。
use strict; use warnings; use Data::Dumper;
print Dumper \%INC;
{
my %INC = ('asdf' => 'asdf');
print Dumper \%INC;
}
print Dumper \%INC;
制作(剪辑):
'feature.pm' => 'C:/Perl/lib/feature.pm'
};
$VAR1 = {
'asdf' => 'asdf'
};
$VAR1 = {
'warnings/register.pm' => 'C:/Perl/lib/warnings/register.pm',
我的案例中的问题似乎不是my %INC
,而是脚本中的%INC = &sub_that_has_my_percent_INC_and_returns_it()
我实际需要require
。现在,反过来,也有use vars qw(%INC)
。取而代之......好吧,我不确定那会破坏什么。
答案 0 :(得分:4)
全局变量%INC
(或%main::INC
或%::INC
)是与使用%INC
创建的词法范围my
完全不同的变量。您可以在子例程中安全地使用my %INC
。
答案 1 :(得分:2)
定义lexicaly scoped my %INC
是可能的,但这个变量绝对没有特殊含义。在使用模块系统时,Perl仅考虑全局%INC
。
您的问题在其他地方
只是为了给你带来一些例子,给出:
Aaa.pm
package Aaa;
warn "Aaa loaded!";
1;
inc.pl
use strict;
use warnings;
use Data::Dumper;
use Aaa;
require Aaa;
warn 1, Dumper \%INC;
{
my %INC;
use Aaa;
require Aaa;
warn 2, Dumper \%INC;
}
warn 3, Dumper \%INC;
my %INC;
use Aaa;
require Aaa;
sub again {
my %INC;
require Aaa;
warn 4, Dumper \%INC;
}
again();
warn 5, Dumper \%INC;
您只会在1和3中看到全局%INC
,而不会对词法变化进行任何更改,Aaa.pm
仍然只会加载一次。
答案 2 :(得分:1)
perldoc vars
表示vars
pragma已被our
关键字取代。
遵循文档的建议似乎对我有用:
package Incentives;
use strict;
use warnings;
use Data::Dump 'dump';
our %INC = ( abc => 123 );
dump \%INC; # ( abc => 123 ),
# different under use vars '%INC';
use List::Util; # Loads just fine
package Test;
use Data::Dump 'dump';
dump \%Incentives::INC; # ( abc => 123 )
dump \%main::INC; # reference to global %INC
1;
答案 3 :(得分:1)
如果触摸全局包变量%INC
,则会遇到问题,但是您可以创建所需的所有名为%INC
的词法,这不会有问题。
$ perl -e'require CGI; my %INC; require CGI;'
$ perl -e'require CGI; local %INC; require CGI;'
Subroutine export_fail redefined at .../Carp.pm line 64.
Subroutine _cgc redefined at .../Carp.pm line 66.
Subroutine longmess redefined at .../Carp.pm line 72.
Subroutine shortmess redefined at .../Carp.pm line 92.
Subroutine croak redefined at .../Carp.pm line 100.
Subroutine confess redefined at .../Carp.pm line 101.
Subroutine carp redefined at .../Carp.pm line 102.
Subroutine cluck redefined at .../Carp.pm line 103.
Constant subroutine Carp::CALLER_OVERRIDE_CHECK_OK redefined at .../Carp.pm line 108.
Subroutine caller_info redefined at .../Carp.pm line 114.
Subroutine format_arg redefined at .../Carp.pm line 181.
Subroutine get_status redefined at .../Carp.pm line 213.
Subroutine get_subname redefined at .../Carp.pm line 222.
Subroutine long_error_loc redefined at .../Carp.pm line 240.
Subroutine longmess_heavy redefined at .../Carp.pm line 268.
Subroutine ret_backtrace redefined at .../Carp.pm line 276.
Subroutine ret_summary redefined at .../Carp.pm line 309.
Subroutine short_error_loc redefined at .../Carp.pm line 324.
Subroutine shortmess_heavy redefined at .../Carp.pm line 348.
Subroutine str_len_trim redefined at .../Carp.pm line 361.
Subroutine trusts redefined at .../Carp.pm line 376.
Subroutine trusts_directly redefined at .../Carp.pm line 396.
Constant subroutine CGI::XHTML_DTD redefined at .../constant.pm line 151.
Subroutine _ops_to_nums redefined at .../overloading.pm line 10.
Subroutine import redefined at .../overloading.pm line 19.
Subroutine unimport redefined at .../overloading.pm line 37.
你说的不是jive。您必须在某处更改全局%INC
而不是词法。
答案 4 :(得分:0)
尝试
no warnings 'redefine';
在那个子程序中,虽然这可能会在将来产生一些有趣的副作用
答案 5 :(得分:0)
我认为我发现了实际问题以及解决问题的方法。
我没有创建两个文件。
file1.pl
有一些潜艇。其中一个潜艇就是这样的:
sub foo {
my %INC = (foo => 'bar'); # lexical variable, does not mess with global %INC
return %INC;
}
file2.pl
看起来像这样:
use vars qw(%INC); # oops! global variable
require 'file1.pl';
sub bar1 {
if (!$INC{'foo'}) {
%INC = &foo(); # this is breaking stuff
}
my $hashref = {
'inc' => \%INC,
}
return $hashref;
}
sub bar2 {
if (!$INC{'foo2'}) {
%INC = &foo();
}
}
# and so on
在我创建的file3.pl
中,我有:
use MyModule;
require 'file2.pl';
my $data = &bar1();
my $obj = MyModule->new();
$obj->doStuff();
现在,当我调用doStuff()
时,它会为全局%INC
中的每个项目打印一个重新定义的警告(由于file2,该项目现在为空)。
我在代码库中搜索了%INC
,发现只有file1和file2才使用它。所以我所做的就是将file2更改为:
use vars qw();
require 'file1.pl';
my %INC; # now lexical, but still the same for all subs in this file
sub bar1 {
if (!$INC{'foo'}) {
%INC = &foo(); # this is not breaking stuff any more
}
my $hashref = {
'inc' => \%INC,
}
return $hashref;
}
sub bar2 {
if (!$INC{'foo2'}) {
%INC = &foo();
}
}
# and so on