Adam has asked for the wisdom of the Perl Monks concerning the following question:

I am a bit confused over @ISA. My understanding was that if a function is not declared in a package, Perl will look in other packages listed in @ISA. But when I ran this simple test, it failed:
#!perl -w use strict; package Top; use Carp; carp( __PACKAGE__ ." has been loaded" ); package Top::level; use vars qw( @ISA ); @ISA = ( 'Top' ); carp( __PACKAGE__ ." has been loaded" ); __END__ Output: Top has been loaded at test.pl line 6 Undefined subroutine &Top::level::carp called at test.pl line 11.
What am I doing wrong? Or am I just mis-using @ISA?

Replies are listed 'Best First'.
(tye)Re: A question of inheritance
by tye (Sage) on Nov 28, 2000 at 23:20 UTC

    @ISA only inherits method calls, not subroutines. If you don't have ->, then @ISA doesn't trigger.

    Update: And even the ubiquitous @ISA=qw(Exporter) is an abuse of inheritance and causes problems. All of the modules that inherit from Exporter.pm should be changed to just do:

    *import= \&Exporter::import;
    so that they "inherit" just the one function from Exporter that they want.

    [Update: ...but don't run off and do this in your own modules just yet! Complete support for this requires some minor patching of Exporter.pm. Worse, you probably won't notice a problem with your module after you make this change so you'll think you are safe until some user of your module tries "require Your::Module 1.05" (or some other feature of Exporter that doesn't currently work without the inheritance sledge having been applied). ]

    This problem has been improved a bit lately by, for example, DynaLoader.pm doing

    *AUTOLOAD = \&AutoLoader::AUTOLOAD;
    instead of inheriting. But I think the documentation for these core modules should be changed to suggest importing the one function you need instead of inheriting willy nilly.

            - tye (but my friends call me "Tye")
      Says tye:
      > ...even the ubiquitous @ISA=qw(Exporter) is
      > an abuse of inheritance and causes problems.
      I think it is the wrong approach to suggest changing all the modules that do this. It also fails to solve the larger problem, which is when class A inherits from class B, but B contains a private utility subroutine that you don't want to inherit.

      People have been talking for a long time about a :method attribute for subroutines. If there were such an attribute, you could simply have a rule that says that only :method subroutines could be inherited. Then the right fix would be very simple: Just tag Exporter::import with the :method attribute.

        I agree that a :method attribute would be a good thing and that inheriting utility functions is a problem.

        I disagree that switching the standard use of Exporter.pm from inheritance to importing wouldn't be a good thing (I'm not suggesting forcing all old modules to be switched to this new usage). Using inheritance to get the single import() method is a bit of a stretch and I still think it would be a problem even with a :method attribute.

        I wonder how hard it would be to get:

        use Exporter qw(import);
        to work? (Part of me say "easy, it probably already works" and part of me worries that that tunnel might be quite long and dark.)

                - tye (but my friends call me "Tye")
      That should probably be:
      BEGIN { require Exporter; *import = Exporter->can("import"); }
      So that Exporter can inherit import if needed, and also so we get the definition at compile time in case there's a prototype.

      -- Randal L. Schwartz, Perl hacker

Re: A question of inheritance
by merlyn (Sage) on Nov 28, 2000 at 23:20 UTC
Re: A question of inheritance
by chipmunk (Parson) on Nov 28, 2000 at 23:21 UTC
    @ISA lookups only occur for method calls (e.g. $obj->method()). For plain function calls, you need to import the functions into the calling package. Exporter is the easiest way to do that.
Re: A question of inheritance
by arturo (Vicar) on Nov 28, 2000 at 23:15 UTC

    You might be ... notice that you're not importing the carp function into the Top::level namespace. This is nowhere NEAR definitive, but perhaps use of Exporter in package Top is called for?

    Update and hopefully more definitive: "The Exporter module implements a default import method which many modules choose to inherit rather than implement their own code." (from my system's perldoc Exporter) My take is that ISA and Exporter work together.

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor