Overriding *all* methods

J

Jack D

I want to subclass a module in order to add some code to *each and every*
method inherited. Is there an easy way to override all methods of a package
without knowing the names of the methods in advance?

Jack
 
D

Darin McBride

Jack said:
I want to subclass a module in order to add some code to *each and every*
method inherited. Is there an easy way to override all methods of a
package without knowing the names of the methods in advance?

I don't think you really want to subclass. I think you want to embed,
and then you can use AUTOLOAD. That is, have the parent object as a
piece of data in your object.
 
B

Brian McCauley

Jack said:
I want to subclass a module in order to add some code to *each and every*
method inherited. Is there an easy way to override all methods of a package
without knowing the names of the methods in advance?

Don't use inheritance - use AUTOLOAD.

sub AUTOLOAD : lvalue {
my ($method) = do { our($AUTOLOAD) =~ /(\w+$)/ };
# added stuff
$method = "ParentClass::$method";
shift->$method(@_);
}

Note lvalued AUTOLOAD doesn't work (actually crashes compiler) in 5.6
 
J

Jack D

Brian McCauley said:
Don't use inheritance - use AUTOLOAD.

sub AUTOLOAD : lvalue {
my ($method) = do { our($AUTOLOAD) =~ /(\w+$)/ };
# added stuff
$method = "ParentClass::$method";
shift->$method(@_);
}

Note lvalued AUTOLOAD doesn't work (actually crashes compiler) in 5.6
Ok - I had to do some O'Reilly searching on this one. I think I understand
how this works. However during my reading - I saw this in Programming Perl:

"After Perl has vainly looked through an object's class package and the
packages of its base classes to find a method, it also checks for an
AUTOLOAD routine in each package before concluding that the method can't be
found."

So now - I'm not sure if this will work because there are other constraints.
i.e. I need to "use The::parentModule" within my module - so this means that
the methods will be found and AUTOLOAD will not be called. Is this a correct
understanding?

I will describe exactly what I am trying to do.

I am trying to create a composite Tk widget which adds line numbers to a
Tk::Text widget (or for that matter any other widget which uses Tk::Text as
a base). In order to catch all user and programmed events for changes to the
contents - I wish to call a subroutine which updates the line numbers
whenever *any* method is called which is related to Tk::Text or Tk::WhatEver
(where WhatEver is derived from Tk::Text)

Here are some constraints:

1. I must allow the name of any Tk::Text derived module to be passed.
2. This module must be "use" d within my package..

Will AUTOLOAD still work in this case?

I have already released a beta version of this called Tk::LineNumberText to
CPAN - but it actually overwrites (ugh!)the Text-based methods - something
which I do not want to do. Hackery - shame..

Jack
 
A

Ala Qumsieh

Jack said:
So now - I'm not sure if this will work because there are other constraints.
i.e. I need to "use The::parentModule" within my module - so this means that
the methods will be found and AUTOLOAD will not be called. Is this a correct
understanding?

No. It will only look for the method in The::parentModule if that is
defined as a base for your module via either:

use base qw/The::parentModule/;
or
our @ISA = qw/The::parentModule/;

If you have Damian Conway's "Object-Oriented Perl", have a look at
Chapter 3, section 3.3.3 for a similar example. If you don't, then why
not? :)

--Ala
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,184
Messages
2,570,978
Members
47,578
Latest member
LC_06

Latest Threads

Top