Evan Carroll
Evan Carroll

Reputation: 1

Using Perl, how do I track where constants are being redefined?

I'm using perl. I keep getting these errors

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

How do I track down what is redefining them. Using the brute force approach I was able to suppress this error one time by removing a compound statement from use base qw/quz qaz/ to use base 'qaz'. I'm thinking this is indicative of some other errors I've got going on. I can hack constant.pm if you know how to add this debugging code.

Also props if there is a Devel:: module that helps me out, or an alternative workflow to figure this out.

The problem seems to be documented here.

Upvotes: 2

Views: 380

Answers (2)

ikegami
ikegami

Reputation: 386331

Add 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

If you want to know where the first declaration occurred, you could override 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.

Upvotes: 3

xxfelixxx
xxfelixxx

Reputation: 6602

I would suggest using the Carp library.

Here is minimal example:

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

Upvotes: 4

Related Questions