Dear monks,
I have few files as follow:
MyTest::Base.pm
package MyTest::Base;
use strict;
no autovivification;
sub new {
bless {}, shift;
}
sub chkAccessRight {
my $self = shift;
print "Base chkAccessRight @_$/";
my ( $usr, $service ) = @_ ;
return 1;
}
sub tryAccess {
my $self = shift;
print "Base tryAccess @_$/";
my ( $usr, $service ) = @_ ;
return $self -> chkAccessRight ( $usr => $service ) ;
}
1;
MyTest::Lite.pm
package MyTest::Lite;
no autovivification;
use parent 'MyTest::Base';
use strict;
sub new {
my $self = shift;
my $parent = $self -> SUPER::new ;
return bless { Parent => $parent, @_} , $self;
}
sub chkAccessRight {
my $self = shift;
print "Lite chkAccessRight @_$/";
if ( $self -> {Usr} ) {
return $self->{Parent}->SUPER::chkAccessRight ( $self->{Usr} ,
+ shift ) ;
}
else {
return $self->{Parent}->SUPER::chkAccessRight ( @_ ) ;
}
return 1;
}
sub tryAccess {
my $self = shift;
print "Lite tryAccess @_$/";
if ( $self -> {Usr} ) {
return $self->{Parent}->SUPER::tryAccess ( $self->{Usr} , shif
+t ) ;
}
else {
return $self->{Parent}->SUPER::tryAccess ( @_) ;
}
}
1;
main.pl
use MyTest::Lite;
use strict;
my $lite = new MyTest::Lite ( Usr => 'guest') ;
$lite -> chkAccessRight ( "app2" ) ;
print "======================$/";
$lite -> tryAccess ( "app1" );
And run the main.pl, I got this output:
Can't call method "SUPER::chkAccessRight" on an undefined value at MyT
+est/Lite.pm line 19.
Lite chkAccessRight app2
Base chkAccessRight guest app2
======================
Lite tryAccess app1
Base tryAccess guest app1
Lite chkAccessRight guest app1
The above codes are snapped (and modified) from my real project, and what I am trying to do is to re-interface the class accessing behavior.
From the last line of output, this is obviously the chkAccessRight() is calling to my overridden sub from MyTest::Lite but I would expect it calls the chkAccessRight() from MyTest::Base
I already have a solution though:
1. Not to use the same method name , so there will be no confusion about the SUPER::, and perl will not attempt to call the overridden method (from Base). BUT, I hope I can maintain the same method name as it seem most appropriate
2. Implement $lite -> tryAccess ( "app1" ); within the MyTest::Lite class, ie. I dont call the SUPER::tryAccess. BUT some other methods are with more relevance to it's SUPER::* methods, so I like to remain calling the methods' super class for their jobs.
It there any better workaround out there ?
Thanks in advance!
================================================
UPDATE & CONCLUSION:
I gave up on the inheritance way, and use the sub AUTOLOAD to return eval "\$self->\{Parent}->$subName\(\@_))". So there will be no more SUPER:: is needed.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.