2

my %INC使用しているスクリプトに、インセンティブに関する値を格納するサブが含まれているのを見つけました%INC。これは決して問題とは思われなかったし、誰も気づかなかった。私にとっては、再定義警告の20画面が生成されました。これは%INC、Perlがdone、required、またはusedを持つすべてのファイル名を保持しているため、かなり大きく、現在は('stuff' => 123)です。

私は本当にサブでこれへのすべての参照の名前を変更する必要がありますか、それとも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)

警告は、クラスの1つのオブジェクトを作成した場合にのみ表示されます(これにはたまたま含まれ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)。それを交換する...まあ、それが何を壊すのかわかりません。

4

6 に答える 6

4

グローバル変数%INC(または%main::INCまたは)は、で作成され%::INCた字句スコープとは完全に異なる変数です。サブルーチンで安全に使用できます。%INCmymy %INC

于 2012-06-29T14:33:39.200 に答える
2

字句スコープを定義する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され、字句に変更を加えることなく、1Aaa.pm回だけロードされます。

于 2012-06-29T15:30:34.617 に答える
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.

あなたが言ったことは冗談ではありません。%INCどこかで字句ではなくグローバルを変更する必要があります。

于 2012-06-29T19:42:04.183 に答える
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;
于 2012-06-29T17:02:13.473 に答える
0

で試してみてください

no warnings 'redefine';

ただし、そのサブルーチンでは、これは将来的にいくつかの興味深い副作用をもたらす可能性があります

于 2012-06-29T14:25:24.010 に答える
0

私は実際の問題とそれに対処する方法を見つけたと思います。

私が作成しなかったファイルが2つあります。

file1.plいくつかの潜水艦がいます。これらの潜水艦の1つは次のようなことをします:

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のために空になりました)。

コードベースを検索したところ、%INCfile1と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
于 2012-06-29T16:58:47.210 に答える