Redefine warnings when subclassing

15 views
Skip to first unread message

Henry Law

unread,
Jun 21, 2022, 1:36:41 PMJun 21
to
There's plainly something I don't understand. I have a file which
contains four packages; the first is a base class and the other three are
subclasses of it. The code runs fine but I'm getting warnings that the
subroutines are redefined; I thought that was the whole purpose of
subclassing! I know I can put "no warnings redefine", but should I have
to?

#!/usr/bin/perl

use strict;
use warnings;
use 5.016;

package A;

sub new{
print "This is the new method for A\n";
}

sub doodle{
print "This is the doodle method for A\n";
}

1;

package B;

use parent 'A';

sub new{
print "This is a subclassed method for B\n";
}

1;

# perl -c A.pm
Subroutine new redefined at /home/henry/Perl/tryout/A.pm line 9.
Subroutine doodle redefined at /home/henry/Perl/tryout/A.pm line 13.
Subroutine new redefined at A.pm line 23.
A.pm syntax OK

PS: there's something really weird going on, because "doodle" isn't even
being subclassed and yet it still gets a warning.

--
Henry Law n e w s @ l a w s h o u s e . o r g
Manchester, England
Message has been deleted

E. Choroba

unread,
Jun 21, 2022, 7:28:03 PMJun 21
to
If you used separate files for the packages, you wouldn't get the warnings. The reason is that when perl sees
use parent 'A';
it tries to load A.pm as it hasn't loaded it yet. Older Perl versions had the current directory in @INC, so the file itself would be found and read again, redefining already defined subroutines.
To prevent that, use separate files for the packages, or, if you really need to include both of them in one file, use the -norequire option for parent:
use parent -norequire => 'A';
This would stop Perl from loading A.pm.

Ch.

Eric Pozharski

unread,
Jun 23, 2022, 1:33:14 PMJun 23
to
with <OOucnQu3LuKfnC__...@giganews.com> Henry Law wrote:

> There's plainly something I don't understand.

Such lovely discussion you have here. I feel like intervining ;)

> I have a file which contains four packages; the first is a base class
> and the other three are subclasses of it. The code runs fine but I'm
> getting warnings that the subroutines are redefined; I thought that
> was the whole purpose of subclassing!

Well, turns out you voided your warranty. Here comes my understanding.

AIII, that's what they call "Koo-Koo module" (in this case it's even
worse). Couple of years ago I've seen some calls for coming to senses
and cleaning CPAN of these nasties. Obviously, those fall on deaf ears.
Anyway, that's what happens:

Noramlly, you 'require' then manipulate '@ISA'. 'parent.pm', 'base.pm',
or whatever else combine these steps for you. Thus, whatever your
habits, 'require' is involved. In your CME you have shebang, that makes
it '.pl'. But your diagnostic says it's '.pm'. Your command-line says
you *run* '.pm' (what can possibly go wrong?). Then, perl does what you
told it to do: compile "A.pm", that module 'require's "A.pm" that hasn't
been compiled yet (perl is lazy here). That leads to redefinition of
subs that already have been compiled, then redefinition of subs that
have been compiled by 'require' after 'require' has finished (look for
yourself, first and second warning refer to fully qualified filename,
then third refers to filename as seen on command-line). Totaly normal,
nothing to see here. Just Perl doing it's thing :[

> I know I can put "no warnings redefine", but should I have to?

Well you have options:

* Do it properly -- one '.pm', one 'package'. Make ovid happy.

* Plug warnings with "no warnings qw/ redefine /". Make perl happy.

* Manipulate '@ISA' directly. Shoot yourself in foot sometime later.

* Search CPAN, probably there is something in support of Koo-Koo
modules, but I don't have any keywords to start with. Make yourself
busy.

* Did I miss something?

*SKIP*
> PS: there's something really weird going on, because "doodle" isn't
> even being subclassed and yet it still gets a warning.

I'm actualy surprised you haven't figured out all this by yourself. I
blame RL.

--
Torvalds' goal for Linux is very simple: World Domination
Stallman's goal for GNU is even simpler: Freedom

Rainer Weikusat

unread,
Jun 26, 2022, 1:59:57 PMJun 26
to
Eric Pozharski <why...@pozharski.name> writes:
> with <OOucnQu3LuKfnC__...@giganews.com> Henry Law wrote:

[...]

>> I know I can put "no warnings redefine", but should I have to?
>
> Well you have options:
>
> * Do it properly -- one '.pm', one 'package'. Make ovid happy.

There's no reason to make someone happy who suffers from Poettering's
disease, ie, from the hard-coded assumption that "all of the world must
work just as my laptop does!".

>
> * Plug warnings with "no warnings qw/ redefine /". Make perl happy.
>
> * Manipulate '@ISA' directly. Shoot yourself in foot sometime later.
>
> * Search CPAN, probably there is something in support of Koo-Koo
> modules, but I don't have any keywords to start with. Make yourself
> busy.
>
> * Did I miss something?

Don't use silly modules implementing unrelated bits of trivial
functionality just because someone can't imagine using one without the
other. That's bad software design.

-----
package Ahnen;

sub import
{
my ($caller, $isa);

shift;
$caller = caller();
$isa = \@{"${caller}::ISA"};

for my $class (reverse(@_)) {
unshift(@$isa, $class) unless eval { $_ eq $class and return 1 for @$isa };
}
}

1;
Reply all
Reply to author
Forward
0 new messages