APM: Deprecated Inheritance problem
Brian Michalk
michalk at awpi.com
Wed Dec 3 15:46:31 CST 2003
Here's the error I'm getting:
Use of inherited AUTOLOAD for non-method Tpwrap::set_height_inches() is
deprecated at /mnt/functions/develop/bin/der_vnet_tp.pm line 582
(#2)
(D deprecated) As an (ahem) accidental feature, AUTOLOAD subroutines are
looked up as methods (using the @ISA hierarchy) even when the
subroutines
to be autoloaded were called as plain functions (e.g. Foo::bar()),
not as methods (e.g. < Foo-bar() >> or < $obj-bar() >>).
This bug will be rectified in Perl 5.005, which will use method lookup
only for methods' AUTOLOADs. However, there is a significant base
of existing code that may be using the old behavior. So, as an
interim step, Perl 5.004 issues an optional warning when non-methods
use inherited AUTOLOADs.
The simple rule is: Inheritance will not work when autoloading
non-methods. The simple fix for old code is: In any module that used
to
depend on inheriting AUTOLOAD for non-methods from a base class named
BaseClass, execute *AUTOLOAD = \&BaseClass::AUTOLOAD during startup.
In code that currently says use AutoLoader; @ISA = qw(AutoLoader); you
should remove AutoLoader from @ISA and change use AutoLoader; to
use AutoLoader 'AUTOLOAD';.
Can't locate auto/Tpwrap/set_height_.al in @INC (@INC contains: blib/arch
blib/lib /mnt/functions/develop/bin /samba/functions/develop/bin
/root/bin c:/Vamos/programs/perl/lib /mnt/despav/samba/functions/develop/bin
c:/Vamos/programs/perl/bin . /usr/lib/perl5/i386-linux /usr/lib/perl5
/usr/lib/perl5/site_perl/i386-linux /usr/lib/perl5/site_perl) at
/mnt/functions/develop/bin/der_vnet_tp.pm line 582 (#3)
Uncaught exception from user code:
...
What I have is a base class that I designed to be used by many other
classes. It is supposed to initialize calibration variables, and if a
command (from the command ethernet socket) is issued to initialize a
variable it doesn't know about, it gives up and sends it to the derived
class for processing. I hope I can summarize without too much code bloat.
package base_class;
...
sub set_cmd_keys { # associate a command with a subroutine reference
my $self = shift;
my $ref_subroutine = shift;
my $varname = shift;
$self->{keys}{cmd}{$varname}{ref_sub} = $ref_subroutine;
}
sub get_cmd_sub { # returns the subroutine reference associated with
setting/getting value for a variable
my $self = shift;
my $varname = shift;
if (defined $self->{keys}{cmd}{$varname}) {
if (defined $self->{keys}{cmd}{$varname}{ref_sub}) {
return $self->{keys}{cmd}{$varname}{ref_sub};
}
}
return undef;
}
...
sub process_command_data {
my $self = shift;
... lots of variables here
$self->get_command_lines();
while (@{$self->{incoming}{command}}) {
... whittle down to a single command, key, value
# for this email, set the parameters manually
$cmd = "LASER_HEIGHT";
$key = "5FT";
$val = undef;
$ref_sub = $self->get_cmd_sub($cmd); # check to see if a subroutine
reference was ever stored for this command
if (defined $ref_sub) { # if a reference was stored, call that
subroutine
my $message = $self->$ref_sub($key, $val);
$self->send_cmd_socks($message); # send the results of the command
} else {
... # process generic commands
}
}
}
package derived_class;
use base base_class; # inherit everything from the base class
use Tpwrap; # this is an XS module that uses a C library to talk to
the laser device driver
sub init {
my $self = shift;
$self->set_cmd_keys($self->can("set_laser_height"), 'LASER_HEIGHT'); #
associate a reference to a subroutine
Tpwrap::init(); # works just fine
}
...
sub set_laser_height {
my $self = shift;
if (@_) {
my $t = shift;
$self->{laser_laser_height} = $t;
Tpwrap::set_height_inches($t);
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is where the problem is
}
return $self->{laser_laser_height}.'IN';
}
I think the problem is that set_laser_height is getting called in a context
from the base class, and of course the base class doesn't know anything
about Tpwrap.
Any help/comments?
More information about the Austin
mailing list