2012-06-29 27 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

相關問題