Как я могу unimport функцию в perl?

Я пытаюсь удалить импортированные символы, чтобы они были недоступны как методы в объекте, но 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;

к сожалению я не могу использовать пространство имен:: autoclean потому что я был ограничен модулями, которые являются только частью core perl (да, глупо, но c'est la vie).

без переписывания namespace::autoclean есть ли способ сделать это?

2 ответов


Я считаю, что пространство имен:: autoclean удаляет glob:

delete $Test0::{carp};

без hardcoding пакет:

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

Если вы настаиваете на том, чтобы оставить strict on, вы можете обмануть strict (но это не более или менее безопасно):

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

PS-почему код из StackOverflow приемлем, если код из CPAN не является?


Я знаю, что это не прямо ответить на ваш вопрос, но простое решение не импортировать функции в первую очередь. Это будет работать просто отлично:

use Carp ();  # import nothing

Carp::carp 'good';