Вызов метода дочернего класса из базового класса в Perl

У меня есть модуль под названием 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

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


person arshad    schedule 22.07.2010    source источник
comment
Этот код серьезно косит на то, что вы пытаетесь сделать. Объектно-ориентированные функции Perl, такие как SUPER, работают с вызовами методов, а не процедурными вызовами функций. . Вы должны перепроектировать это.   -  person daxim    schedule 22.07.2010


Ответы (2)


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 теперь вызывает авторизацию с оператором ->, что является синтаксисом вызова метода. Разница между :: и -> здесь большая. Прежде всего, когда вы вызываете функцию с помощью ->, мы называем ее «методом», а не «подпрограммой». Во-вторых, методу всегда передается "$self" в качестве первого аргумента. В случае метода пакета $self — это просто строка, содержащая имя пакета. В случае объекта $self является ссылкой на объект. В-третьих, методы отправляются с использованием объектно-ориентированной иерархии, которую вы здесь пытаетесь использовать.

Теперь вы заметите, что 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.

person masonk    schedule 22.07.2010

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

use base 'Site::Auth';

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

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

/I3az/

person draegtun    schedule 22.07.2010