2012-04-24 34 views
6

私はオブジェクトのメソッドとして利用できないようにインポートされたシンボルを削除しようとしていますが、noが機能していないようで、多分私は何かを理解していないか、別の方法があります。私はコアのperlの一部のみ(うん愚かしかしセラヴィが争う)されているモジュールに制限されてきたのでperlで関数をインポートするにはどうしたらいいですか?

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を使用することはできません。

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

+0

なぜnamespace :: auto cleanがこれを行うのですか?それはあなたが望むことをしますが、たとえそれをモジュールとして使用しなくても、それが何かをするのを避けたいのです。なぜなら、まったく理由がないかのように、仕事を簡単にする方法がなければならないからです。 –

+0

@briandfoy私は可能性がありますが、私は単純な方法があるかもしれないと考えました。 – xenoterracide

答えて

13

私は、名前空間と信じ:: AUTOCLEANはグロブ削除:パッケージをハードコーディングせずに

delete $Test0::{carp}; 

を:

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

あなたは上の厳しい残しを主張した場合、あなたは厳しいことをだますことができます(しかしそれ以上に安全です):

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

PS — CPANからのコードがない場合、なぜStackOverflowのコードが受け入れられますか?

+0

p.s. F *は知っている。 NIHSで時期尚早のオプティマイザを正常にするために疲れました。 – xenoterracide

+0

と@ IlmariKaronenの[回答](http://stackoverflow.com/a/10307099/206466)の組み合わせを使用して、私が一度使用している場所をインポートしないようにします。 – xenoterracide

11

これはあなたの質問に直接答えるものではありませんが、簡単な回避策は最初に関数をインポートすることではありません。これはうまく動作します:

use Carp(); # import nothing 

Carp::carp 'good'; 
関連する問題