tags:

views:

102

answers:

2

I have module called Mobile::Auth to authorize and redirect to the login page. I wanted to access all methods from Site::Auth in my Mobile::Auth except a method '*redirect_to_login_page*', which I have specific one for my Mobile::Auth. I did something like this..

package Mobile:Auth;
use base Site::Auth;
sub redirect_to_login_page{
  #get_my_mobile_specific
}
1;

and in my Mason component file I put..

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

and here is how my Site::Auth looks like

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

Authorization works , but my problem is when I call 'authorize' method from Mobile::Auth it should call Site::Auth::authorization method and *Mobile::Auth::redirect_to_login_page* instead of *Site::Auth::redirect_to_login_page*

Guys, anyone can give me a clue how to do this. Thanks in advance.

+1  A: 

One problem is that you need to quote the parent class:

use base 'Site::Auth';

If you had use strict; present then you would have got an error with your code :)

BTW... you mention Moose in your tags but the code example doesn't use it.

/I3az/

draegtun
+2  A: 

Mobile::Auth doesn't have an authorize sub.

Mobile::Auth::authorize($args)

should die, given what you've shown.

As Daxim pointed out, you aren't using method syntax, and therefore aren't invoking perl's method dispatch. You have two options to fix this.

The first way is to call the that sub you actually want, which is

Site::Auth::authorize($args)

followed by

Mobile::Auth::redirect_to_login_page

However, if you're trying to do this OO, and I think you are, you could try package methods (which are less common than object methods, but at least correct):

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);

Please note a few changes: Site::Auth::authorize() now expects $self to be the first argument, and Mobile::Auth now calls authorize with the -> operator, which is the method invocation syntax. The difference between :: and -> here is large. First of all, when you call a function with ->, we call it a "method" instead of a "sub". Second, the method is always passed "$self" as the first argument. In the case of a package method, $self is just a string containing the name of the package. In the case of an object, $self is a reference to the object. Third, methods are dispatched using the OO hierarchy that you are trying to use here.

Now you'll notice that Mobile::Authorize defines its own redirect_to_login_page() but does not define a validate_credentials() or authorize() sub. (Strictly speaking, you didn't have to factor out validate_credentials() for what follows, but you should, so I did.)

How does it work? Mobile::Auth->authorize() travels up the chain until it finds Site::Auth->authorize, then calls it. Site::Auth->authorize gets $self as "Mobile::Auth". It calls Mobile::Auth->validate_credentials, which perl eventually dispatches as Site::Auth->validate_credentials. It then calls Mobile::Auth->redirect_to_login_page, which is actually defined in package Mobile::Auth, so it gets called from there.

Also, you really need to read http://perldoc.perl.org/perlobj.html cover-to-cover. That should give you the basics on objects in perl.

masonk