in reply to A question of inheritance

@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")

Replies are listed 'Best First'.
Re: (tye)Re: A question of inheritance
by Dominus (Parson) on Nov 28, 2000 at 23:56 UTC
    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")
Re: (tye)Re: A question of inheritance
by merlyn (Sage) on Nov 28, 2000 at 23:31 UTC
    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