http://www.perlmonks.org?node_id=199319


in reply to Carp; errors ala DBI

Please don't use AUTOLOAD in code for distribution , UPDATE, without using NEXT.
Thanks to adrianh for correcting me.

AUTOLOAD is a namespace hog living in the global namespace.
Client code can't avoid your AUTOLOAD routine.

In your case it is an inappropriate solution. You know
the names of the routines you want to call.

You might want to use a constant for config branching:

use constant ERRSTR => 1; if ( ERRSTR) { # errstr stuff }else{ # carp stuff }
this will eliminate the unneeded branch at compile time.

UPDATED: because I was behind times regarding existence of NEXT.

Replies are listed 'Best First'.
Re: Carp; errors ala DBI
by pope (Friar) on Sep 20, 2002 at 05:51 UTC
    Please don't use AUTOLOAD in code for distribution.

    You must be kidding, don't you? :-)

    At least I saw two good modules which uses AUTOLOAD very well: CGI.pm and matts's DBIx::AnyDBD. CGI.pm uses it to delay compilation of certain subs - aka lazy compilation. In DBIx::AnyDBD, AUTOLOAD "inherits" DBI's database handles methods. At a glance, this is also doable by subclassing the DBI::db package. Dunno why matts chooses the AUTOLOAD approach instead of subclassing.

      Yes, I am serious. Update: But use the relatively new NEXT and all the problems can go away.

      AUTOLOAD is a powerful and facile tool: a beautiful thing.
      I like it a lot. So there can be overriding motives to use
      AUTOLOAD, but if possible it is to be avoided by module
      publishers.

      It is a name greedy pig.

      The way Perl resolves a call is:

      1. Seek routine in package.
      2. If method: seek method in base classes.
      3. Seek AUTOLOAD in package.
      4. If method: seek AUTOLOAD in base classes.

      The following code demonstrates the problem.

      #!/usr/bin/perl -w use strict; package Mumma; use vars qw( $AUTOLOAD ); sub AUTOLOAD { print "$AUTOLOAD resolved to Mumma::AUTOLOAD\n"; } package Poppa; use vars qw( $AUTOLOAD ); sub AUTOLOAD { print "$AUTOLOAD resolved to Poppa::AUTOLOAD\n"; } # Baby doesn't know that Mumma & Poppa are secret AUTOLOADERs package Baby; use vars qw( @ISA $AUTOLOAD ); @ISA = qw( Poppa Mumma ); # Order is significant. sub new { bless {}, ref $_[0] || $_[0] } package main; use vars qw( $AUTOLOAD); # Baby is supposed to live in a caring universe. sub UNIVERSAL::AUTOLOAD { print "$AUTOLOAD resolved to UNIVERSAL::AUTOLOAD\n"; } my $c = Baby->new(); # first &AUTOLOAD found hides rest. $c->wants_mumma(); $c->wants_poppa(); $c->wants_universal_truth();

        Basically I agree, it can be a problem in complex class hierarchies. However:

        • We now have the lovely NEXT that allows us to write AUTOLOAD routines that gracefully decline. I would imagine that it will even be efficient once perl6 hits the streets :-)
        • I don't have an issue with AUTOLOAD as long as the module author documents it's presence.
        • It's nearly always possible to get around the problem with a bit of trivial object delegation.
        • If your code isn't OO it's not an issue