2012-06-29 26 views
2

我刚刚发现了一个我们正在使用的脚本,其中有一个说my %INC的子,它存储了一些关于激励的值,因此%INC。这似乎不是一个问题,或者从来没有人注意过。对我来说,它产生了20个重新定义警告屏幕,因为%INC,保存所有文件名Perl有do ne,require d或use d,非常大,现在是('stuff' => 123)是否可以诱使Perl使用变量%INC并仍然保持全局%INC不变?

我真的必须去重命名每个单引用这个在子,还是有另一种方式让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,而是在我实际上是require脚本的%INC = &sub_that_has_my_percent_INC_and_returns_it()。现在,反过来,也有use vars qw(%INC)。替换它......好吧,我不确定那会是什么样的结果。

+3

我打算和建立这个的人聊聊天...... – simbabque

+0

你的意思是'@ INC'? – mkb

+0

本地%INC;会更有意义。我想你现在不能改变它而不会造成意想不到的后果,对吧? – d5e5

回答

4

一些有趣的副作用全局变量%INC(或%main::INC%::INC)是一个完全不同的变量从词汇范围%INC,用my创建。您可以在子程序中安全地使用my %INC

+0

我不这么认为。我编辑了问题以显示警告的样子。 – simbabque

+0

刚才检查一下自己,看看编辑过的问题。问题在于高一层。还是很奇怪。 – simbabque

0

尝试

no warnings 'redefine';

在子程序

,虽然,这可能在未来

+2

谢谢,但我没有试图不显示警告,我试图解决一个大失礼。 – simbabque

2

定义词法作用域my %INC是可能的,但是这个变量绝对没有特别的含义。在使用模块系统时,Perl仅考虑全局%INC

你的问题是其他地方

只是为了给招待你有例子,:

AAA级。下午

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全球%INC和3,没有任何改变词汇者和Aaa.pm仍将只有一次加载。

+1

谢谢你的解释。我也想到了。问题是在下一个脚本中有一个'use vars'%INC''和几个'sub INC',它们共享'my%INC'的sub所返回的'%INC'。我现在试图摆脱这一点。 – simbabque

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完全使用它。所以我所做的就是改变文件2到这一点:

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 
1

perldoc vars说,vars编译已被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; 
+0

这是正确的。但在我的情况下,'use vars' /'我们的%INC'不在'package'中,而是在'main ::'中。我调整了你的代码,现在它显示了警告。在“我们的%INC”之前,它具有正常值。之后,它有'abc => 123'以及一些适当的值,如'Exporter.pm','List/Util.pm'和'vars.pm'。我想''我们''它只是删除'main ::'中定义的那些,并留下来自'Test'的那些。很奇怪。 – simbabque

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而不是某个词汇。

+0

感谢您的简单例子。你当然是对的。我(做了)。在[我自己的答案](http://stackoverflow.com/a/11265936/1331451)我更详细地解释。 – simbabque