6

インポートされたシンボルをオブジェクトのメソッドとして使用できないように削除しようとしていますが、no機能していないようです。理解できないか、別の方法があります。

use 5.014;
use warnings;
use Test::More;

# still has carp after no carp
package Test0 {
    use Carp qw( carp );
    sub new {
        my $class = shift;
        my $self  = {};

        carp 'good';

        bless $self, $class;
        return $self;
    }
    no Carp;
}

my $t0 = Test0->new;

ok( ! $t0->can('carp'), 'can not carp');

# below passes correctly
package Test1 {
    use Carp qw( carp );
    use namespace::autoclean;

    sub new {
        my $class = shift;
        my $self  = {};

        carp 'good';

        bless $self, $class;
        return $self;
    }
}
my $t1 = Test1->new;
ok( ! $t1->can('carp'), 'can not carp');
done_testing;

残念ながら、私はnamespace::autocleanを使用できません。これは、コア perl の一部にすぎないモジュールに制限されているためです (愚かですが、c'est la vie です)。

書き直すだけでなくnamespace::autoclean、これを行う方法はありますか?

4

2 に答える 2

13

namespace :: autocleanはglobを削除すると思います:

delete $Test0::{carp};

パッケージをハードコーディングせずに:

my $pkg = do { no strict 'refs'; \%{ __PACKAGE__."::" } };
delete $pkg->{carp};

strictをオンのままにすることを主張する場合は、strictをだますことができます(ただし、多かれ少なかれ安全ではありません)。

my $pkg = \%::;
$pkg = $pkg->{ $_ . '::' } for split /::/, __PACKAGE__;
delete $pkg->{carp};

PS — CPANからのコードが受け入れられないのに、StackOverflowからのコードが受け入れられるのはなぜですか?

于 2012-04-24T22:50:06.663 に答える
11

これがあなたの質問に直接答えないことはわかっていますが、簡単な回避策は、最初から関数をインポートしないことです。これはうまくいきます:

use Carp ();  # import nothing

Carp::carp 'good';
于 2012-04-24T22:49:01.130 に答える