Вызов метода дочернего класса из базового класса в Perl - PullRequest
1 голос
/ 22 июля 2010

У меня есть модуль с именем Mobile::Auth для авторизации и перенаправления на страницу входа.Я хотел получить доступ ко всем методам из Site::Auth в моем Mobile::Auth, кроме метода redirect_to_login_page, который у меня есть для моего Mobile::Auth.

. Я сделал что-то подобное ...

package Mobile:Auth;
use base Site::Auth;

sub redirect_to_login_page{
  #get_my_mobile_specific
}
1;

и в свой файл компонентов Mason я помещаю ..

use Mobile::Auth;
Mobile::Auth::authorize($args);

и вот как выглядит Site::Auth

package Site::Auth;

....

   sub authorize {
     #.....
     if (!$authorize) {
       redirect_to_login_page($args);
     }
    }
    sub redirect_to_login_page{ 
     # redirect to the login page  
    }
    1;

Авторизация работает, но моя проблемакогда я вызываю authorize метод из Mobile::Auth, он должен вызывать Site::Auth::authorization метод и Mobile::Auth::redirect_to_login_page вместо Site::Auth::redirect_to_login_page

Ребята, любой может дать мне подсказку, как это сделать.Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 22 июля 2010

Mobile :: Auth не имеет авторизационной подписки.

Mobile::Auth::authorize($args)

должен умереть, учитывая то, что вы показали.

Как указал Даксим, вы не используете синтаксис метода и, следовательно, не вызываете диспетчеризацию метода perl. У вас есть два варианта исправить это.

Первый способ - вызвать тот сабвуфер, который вам действительно нужен, то есть

Site::Auth::authorize($args)

с последующим

Mobile::Auth::redirect_to_login_page

Однако, если вы пытаетесь сделать это OO, и я думаю, что вы, вы можете попробовать методы пакета (которые менее распространены, чем методы объекта, но, по крайней мере, правильно):

package Site::Auth;
#....
sub authorize {
    my ( $self, @args ) = @_;

    my $authorized = $self->validate_credentials(@args);

    if( !$authorized ) {
        $self->redirect_to_login_page(@args);
    }
}
sub redirect_to_login_page{ 
    my ( $self, @args ) = @_;
 # redirect to the login page 
}
sub validate_credentials {
    my ( $self, @args ) = @_;
    # This is what you had in #..... before
    return $authorized
}
1;

package Mobile:Auth;
use base 'Site::Auth';

sub redirect_to_login_page {
    my ( $self, @args ) = @_;
    #...
}
1;

### in Mason
use Mobile::Auth;
Mobile::Auth->authorize($args);

Обратите внимание на некоторые изменения: Site :: Auth :: authorize () теперь ожидает, что $ self будет первым аргументом, а Mobile :: Auth теперь вызывает authorize с оператором ->, который является синтаксисом вызова метода. Разница между :: и -> здесь велика. Прежде всего, когда вы вызываете функцию с помощью ->, мы называем ее «методом» вместо «sub». Во-вторых, метод всегда передает «$ self» в качестве первого аргумента. В случае метода пакета $ self - это просто строка, содержащая имя пакета. В случае объекта $ self является ссылкой на объект. В-третьих, методы отправляются с использованием иерархии OO, которую вы пытаетесь использовать здесь.

Теперь вы заметите, что Mobile :: Authorize определяет свой собственный redirect_to_login_page (), но не определяет подпрограмму validate_credentials () или authorize (). (Строго говоря, вам не нужно было выделять validate_credentials () для дальнейших действий, но вы должны это сделать, как я.)

Как это работает? Mobile :: Auth-> authorize () перемещается вверх по цепочке, пока не находит Site :: Auth-> authorize, а затем вызывает его. Site :: Auth-> authorize получает $ self как «Mobile :: Auth». Он вызывает Mobile :: Auth-> validate_credentials, который perl в конечном итоге отправляет как Site :: Auth-> validate_credentials. Затем он вызывает Mobile :: Auth-> redirect_to_login_page, который фактически определен в пакете Mobile :: Auth, поэтому он вызывается оттуда.

Кроме того, вам действительно нужно прочитать http://perldoc.perl.org/perlobj.html от корки до корки. Это должно дать вам основы для объектов в Perl.

1 голос
/ 22 июля 2010

Одна проблема заключается в том, что вам нужно процитировать родительский класс:

use base 'Site::Auth';

Если бы у вас был use strict; подарок, вы бы получили ошибку с вашим кодом:)

Кстати ... вы упоминаете Moose в своих тегах, но пример кода не использует его.

/ I3az /

...