【问题标题】:Calling child class method from Base Class in PerlPerl从基类调用子类方法
【发布时间】:2010-07-22 06:42:52
【问题描述】:

我有一个名为Mobile::Auth 的模块来授权并重定向到登录页面。我想在我的Mobile::Auth 中访问来自Site::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;

授权有效,但我的问题是当我从Mobile::Auth 调用authorize 方法时,它应该调用Site::Auth::authorization 方法和Mobile::Auth::redirect_to_login_page 而不是Site::Auth::redirect_to_login_page

伙计们,任何人都可以告诉我如何做到这一点。提前致谢。

【问题讨论】:

  • 这段代码对你试图做的事情是认真的。 Perl 的 OO 功能(如 SUPER)适用于方法调用,而不是过程函数调用。你必须重新设计它。

标签: perl oop mason


【解决方案1】:

Mobile::Auth 没有授权子。

Mobile::Auth::authorize($args)

应该死,鉴于你所展示的。

正如 Daxim 指出的,您没有使用方法语法,因此没有调用 perl 的方法分派。您有两种选择来解决此问题。

第一种方法是调用你真正想要的那个sub,即

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 是对该对象的引用。第三,使用您在此处尝试使用的 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 中对象的基础知识。

【讨论】:

    【解决方案2】:

    一个问题是你需要引用父类:

    use base 'Site::Auth';
    

    如果您有 use strict; 存在,那么您的代码会出错:)

    顺便说一句...您在标签中提到了Moose,但代码示例没有使用它。

    /I3az/

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 2016-10-05
      • 2011-01-22
      • 2018-10-15
      • 2012-06-28
      • 2017-12-13
      • 2010-12-05
      • 1970-01-01
      • 2012-08-04
      相关资源
      最近更新 更多