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};

如果你坚持要保持严格,你可以愚弄严格(但它或多或少不安全):

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 回答