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