Конфликт имени в Perl - PullRequest
       12

Конфликт имени в Perl

4 голосов
/ 09 сентября 2010

Я нахожусь в ситуации, когда модуль, который я использую, имеет функцию, имя которой точно совпадает с именем в моем собственном модуле. Когда я пытаюсь вызвать функцию в моем модуле (OO Perl, поэтому $self->function), она вызывает функцию из другого модуля.

Я уже справился с этим, переименовав свою функцию, но, как интересно, есть ли способ явно вызвать функцию из моего модуля?

редактировать: по сути это то, что я делаю

package Provider::WTO;

use base qw(Provider); # Provider contains a method called date

use utilities::utils; #not my module so don't blame me for the horrendous name :-)
...
sub _get_location
{
    my $self = shift;
    return $self->date."/some_other_string"; # calls utilities::utils::date()
}

Ответы [ 3 ]

8 голосов
/ 09 сентября 2010

Если конфликт имен вызван импортом из другого модуля, вы можете рассмотреть либо Sub::Import, что позволяет легко переименовать импорт, даже если экспортирующий модуль явно не поддерживает это, либо namespace::autoclean / namespace::clean.

package YourPackage;

use Sub::Import 'Some::Module' => (
    foo => { -as => 'moo' },
); # imports foo as moo

sub foo { # your own foo()
    return moo() * 2; # call Some::Module::foo() as moo()
}

Модули очистки пространства имен будут полезны, только если импорт затеняет любой из ваших методов с помощью функции, а не в любом другом случае:

package YourPackage;

use Some::Module; # imports foo
use Method::Signatures::Simple
use namespace::autoclean; # or use namespace::clean -except => 'meta';

method foo {
    return foo() * 2; # call imported thing as a function
}

method bar {
    return $self->foo; # call own foo() as a method
}

1;

Таким образом, импортированная функция будет удалена после компиляции вашего модуля, когда вызовы функции foo () уже связаны с импортом. Позже, во время выполнения ваших модулей, вместо этого будет установлен метод foo. Разрешение метода всегда происходит во время выполнения, поэтому любые вызовы методов -> foo будут разрешены для вашего собственного метода.

Кроме того, вы всегда можете вызвать функцию по ее полному имени и не импортировать ее.

use Some::Module ();
Some::Module::foo();

Это также можно сделать для методов, полностью отключив поиск метода во время выполнения:

$obj->Some::Module::foo();

Однако необходимость делать это обычно является признаком плохого замысла, и вам, вероятно, следует отступить немного назад и объяснить, что вы сделали, чтобы вы попали в эту ситуацию.

3 голосов
/ 09 сентября 2010

Вам нужна эта подпрограмма из модуля-нарушителя?Не зная больше об этом, я думаю, что быстрое решение состоит в том, чтобы явно не импортировать его с пустым списком импорта:

 use Interfering::Module ();

Если вам нужны другие импортированные вещи, вы можете указать те, которые вам нужны:*

 use Interfering::Module qw(sub1 sub2);

Если список экспорта, который вы хотите, очень длинный, вы можете просто исключить мешающую подпрограмму:

 use Interfering::Module qw(!bad_sub);

Если ничего из этого не сработает, вам придется больше рассказать оМешающий модуль.

0 голосов
/ 09 сентября 2010

Вы уверены, что это происходит при вызове метода (т. Е. $ Self-> function), а не при обычном вызове?

Если это так, то я вижу, как это происходит, только если твой модуль расширяет другой модуль, и ты не определяешь рассматриваемый метод, и модуль, который вы расширяете, определяет функцию с тем же именем, что и метод, который вы пытаетесь вызвать.

В любом случае вы не можете импортировать нарушающую функцию в ваше пространство имен с помощью use Foreign::Module ().

Если это обычный вызов функции, который становится закрытым, вы можете ссылаться на него как Your::Module->function.

...