Использование __PACKAGE__ внутри моих методов плохо для наследования? - PullRequest
6 голосов
/ 30 ноября 2009

Если внутри моего кода у меня будут звонки типа:

__PACKAGE__->method;

будет ли это ограничивать удобство использования этого модуля, если этот модуль наследуется?

Ответы [ 4 ]

9 голосов
/ 30 ноября 2009

Это зависит от того, что вы хотите сделать:

#!/usr/bin/perl

package A;

use strict; use warnings;

sub new { bless {} => $_[0] }

sub method1 {
    printf "Hello from: %s\n", __PACKAGE__;
}

sub method2 {
    my $self = shift;
    printf "Hello from: %s\n", ref($self);
}

package B;

use strict; use warnings;
use parent 'A';

package main;

my $b = B->new;

$b->method1;
$b->method2;

Выход:

Hello from: A
Hello from: B
6 голосов
/ 30 ноября 2009

Если вы намереваетесь наследовать этот метод, вызывайте его по референту и не полагайтесь на пакет, в котором вы его нашли. Если вы намереваетесь вызвать метод, внутренний для пакета, который не сможет увидеть ни один другой пакет, тогда это может быть хорошо. Более полное объяснение есть в Промежуточном Perl и, вероятно, в perlboot (это отрывок из книги).

В общем, я стараюсь не использовать __PACKAGE__, если не пишу modulino .

Почему вы пытаетесь использовать __PACKAGE__?

3 голосов
/ 30 ноября 2009

«Это зависит». это правильный ответ. Относительно редко действительно требуется имя пакета; обычно у вас будет экземпляр или имя класса для начала. Тем не менее, бывают случаи, когда вам действительно нужно имя пакета - __PACKAGE__ явно инструмент для этой работы, превосходящий буквальное. Вот несколько рекомендаций:

Никогда не вызывайте методы из __PACKAGE__ внутри методов, так как это делает для наследников невозможным изменить вашу реализацию, просто переопределив вызываемый метод. Вместо этого используйте $self или $class.

Старайтесь избегать __PACKAGE__ внутренних методов в целом. Каждое использование __PACKAGE__ добавляет немного негибкости. Иногда гибкость - это то, что вы хотите (потому что вам нужно разрешение во время компиляции или вы очень хотите контролировать, где хранится информация), но будьте уверены, что то, что вы хотите, стоит своих затрат. Вы будете благодарить себя позже.

За пределами методов у вас нет доступа к $self, и вы должны вызывать методы с __PACKAGE__ вместо литерала. Это главным образом важно для объявлений времени компиляции, подобных тем, которые предоставляются Class::Accessor.

3 голосов
/ 30 ноября 2009

Это зависит. Иногда __PACKAGE__->method() это именно то, что вам нужно.

В противном случае лучше использовать ref($self)->class_method() или $self->method().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...