使用Perl,如何跟踪重定义常量的位置?

时间:2016-04-21 03:54:37

标签: perl compiler-warnings circular-dependency

我正在使用perl。我一直收到这些错误

Constant subroutine Samp::foo redefined at /usr/local/share/perl/5.20.2/constant.pm
Constant subroutine Samp::bar redefined at /usr/local/share/perl/5.20.2/constant.pm 
Constant subroutine Samp::baz redefined at /usr/local/share/perl/5.20.2/constant.pm

如何追踪重新定义它们的内容。使用强力方法,我可以通过从use base qw/quz qaz/移除use base 'qaz'的复合语句来抑制此错误一次。我认为这表明我还有其他一些错误。如果您知道如何添加此调试代码,我可以破解constant.pm

如果有一个Devel::模块可以帮助我,也可以使用其他工作流来解决这个问题。

问题似乎是documented here

2 个答案:

答案 0 :(得分:4)

我建议使用Carp库。

这是最小的例子:

<强> Foo.pm

package Foo;

use Exporter 'import';
@EXPORT_OK = qw( abc );

use constant abc => 123;
1;

<强> foo.pl

#!/usr/bin/env perl

use strict;
use warnings;

use Foo qw( abc );
use Carp;
$Carp::Verbose = 1;
$Carp::CarpLevel = 2;
$SIG{__WARN__} = sub { carp(@_) };

print "Before redefine\n";
eval "use constant abc => 456;";
print "After redefine\n";

perl foo.pl

Before redefine
Constant subroutine main::abc redefined at /usr/share/perl5/vendor_perl/constant.pm line 140.
at (eval 1) line 1.
    main::BEGIN() called at (eval 1) line 1
    eval {...} called at (eval 1) line 1
    eval 'use constant abc => 456;' called at foo.pl line 13
After redefine

答案 1 :(得分:3)

添加use Carp::Always;

$ perl -we'
   use constant FOO => 1;
   use constant FOO => 1;
'
Constant subroutine main::FOO redefined at /usr/share/perl/5.14/constant.pm line 136.

$ perl -MCarp::Always -we'
   use constant FOO => 1;
   use constant FOO => 1;
'
Constant subroutine main::FOO redefined at /usr/share/perl/5.14/constant.pm line 136
        constant::import('constant', 'FOO', 1) called at -e line 3
        main::BEGIN() called at -e line 3
        eval {...} called at -e line 3

如果您想知道第一个声明发生的位置,可以覆盖constant::import

perl -we'
   use Carp qw( cluck );
   BEGIN {
      require constant;
      my $old = \&constant::import;
      my $new = sub {
         if (ref($_[1])) {
            cluck("$_ declared") for keys %{ $_[1] };
         } else {
            cluck("$_[1] declared");
         }
         goto &$old;
      };
      no warnings qw( redefine );
      *constant::import = $new;
   }

   use constant FOO => 1;
   use constant FOO => 1;
'
FOO declared at -e line 10
        main::__ANON__('constant', 'FOO', 1) called at -e line 18
        main::BEGIN() called at -e line 18
        eval {...} called at -e line 18
FOO declared at -e line 10
        main::__ANON__('constant', 'FOO', 1) called at -e line 19
        main::BEGIN() called at -e line 19
        eval {...} called at -e line 19
Constant subroutine main::FOO redefined at /usr/share/perl/5.14/constant.pm line 136.