2013-10-09 3 views
3

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

package Parent; 
use strict; 
use warnings; 

sub dispatch{ 
    my ($self, $funcname) = @_; 


    no strict "refs"; 
    if($self->can($funcname)){ 
    $self->$funcname(); 
    } 
    else{ 
    $self->default_func(); 
    } 
    use strict; 
} 

sub a{ 
    ... 
} 

sub b{ 
    ... 
} 

#...lots more functions... 

sub default_func{ 
    .. 
} 

package Child; 
use strict; 
use warnings; 
use Parent; 

our @ISA = qw(Parent) 

sub c{ 
    .. 
} 

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

package Parent; 
use strict; 
use warnings; 

{ 
    my $funcs ||= { 
    a => sub { shift->a }, 
    b => sub { shift->b }, 
    c => sub { shift->c }, 
    #...lots of functions... 
    DEFAULT => sub {shift->default_func} 
    } 
    sub dispatch{ 
    my ($self, $funcname) = @_; 
    my $func = $funcs->{$funcname} || $funcs->{DEFAULT}; 
    $self->$func(); 
    } 
} 

Кроме того, я считал поворот таблицы отправки на в качестве члена так, чтобы родительский класс не должен быть в курсе дочерних классов. Затем каждый дочерний класс добавляет свои собственные функции в таблицу рассылки. Первоначально я не хотел, чтобы стол для рассылки был участником, так как я только хотел, чтобы он подвергался одной функции, но, возможно, это неизбежно. Но в конце концов, превращение его в члена не устраняет проблему дополнительного шаблона и обслуживания.

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

+2

В вашем первом примере нет символических ссылок. '$ self-> can' возвращает ссылку на код, а' $ self -> $ coderef' будет работать нормально под 'use strict'. – friedo

+3

'$ self -> $ name_of_method()' отлично работает под 'use strict'. Нет необходимости в 'no strict 'refs'' вообще. – cjm

+0

Я не понимаю. Я использую строку вместо имени функции, которая заставляет perl искать имя функции в своей таблице символов. Разве это не определение символической ссылки? –

ответ

3

Ваш пример исходного кода работает под use strict. Форма $obj->$method(...) не требует символических ссылок. Это широко используемый метод и считается хорошей практикой.

Также обратите внимание, что даже если вам нужно было no strict, в конце функции, как в вашем примере, нет необходимости в use strict. strict - лексическая прагма, поэтому ее эффекты в любом случае ограничены его областью.

0

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

package Parent; 
use vars qw($AUTOLOAD); 
sub AUTOLOAD { 
    return if $AUTOLOAD =~ m/^.*::(DESTROY)$/; 
    my ($self, @params) [email protected]_; 
    return $self->$AUTOLOAD() if($self->can($AUTOLOAD)){ 
    return $self->default_func(); 
} 
Смежные вопросы