Reputation: 437
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.
Upvotes: 1
Views: 1515
Reputation: 9778
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.
Upvotes: 2
Reputation: 22560
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/
Upvotes: 1