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

So I write a response to this blogs.perl.org post titled, 'Who Tests the Tester? Me!!!' by lichtkind and almost as soon as I hit the submit button I take a closer look at my test and say, 'oops...I forgot to change the class to the new subclass...I'll just change that and rerun my tests. No problem...'

t/01.t ............ ok t/hsltupletest.t .. 1/? # Failed test 'A is now between 0 and 360 since it is degrees' # at t/hsltupletest.t line 22. # Looks like you failed 1 test of 6. t/hsltupletest.t .. Dubious, test returned 1 (wstat 256, 0x100) Failed 1/6 subtests t/tupletest.t ..... ok Test Summary Report ------------------- t/hsltupletest.t (Wstat: 256 (exited 1) Tests: 6 Failed: 1) Failed test: 6 Non-zero exit status: 1 Files=3, Tests=12, 0 wallclock secs ( 0.08 usr 0.02 sys + 0.49 cusr + 0.07 csys = 0.66 CPU) Result: FAIL

Denied!

Debugging reveals something extremely strange...

main::(./t/hsltupletest.t:8): my $prospectTupleRef = [qw~a b c~]; DB<1> n main::(./t/hsltupletest.t:10): my $tuple = HSLTuple->new($prospectT +upleRef, 'HSL'); DB<1> n main::(./t/hsltupletest.t:12): ok($tuple->is_valid($prospectTupleRe +f) == 0, "A B C is an array but not an HSL tuple"); DB<1> x $tuple 0 FakeTuple=HASH(0x5b2e6ee12a70) 'axes' => 3 'space_name' => 'HSL' 'tupledata' => undef DB<2>

What? It says it is a FakeTuple even though I clearly used the HSLTuple! Unsurprisingly, it calls the is_valid() method of FakeTuple:

main::(./t/hsltupletest.t:20): ok($tuple->is_valid([qw~361 62 99~]) + == 0 , "A must be between 0 and 360 since it is degrees"); DB<2> s FakeTuple::is_valid(FakeTuple.pm:34): 34: my ($self, $data2Check) = @_; DB<2> l 34==> my ($self, $data2Check) = @_; 35: my $result = 0; 36: for(0..2){$result++ if ($data2Check->[$_]=~m/\d+/ && 37 $data2Check->[$_] >= 0 && 38 $data2Check->[$_] <= 100)}; 39 40: return ( $result == $self->no_of_axes() ) ? 1 : 0; 41 } 42 43 # code (loosely) borrowed from Basis.pm DB<2>

Why did it not use my derived class and call my overridden method?

Celebrate Intellectual Diversity

Replies are listed 'Best First'.
Re: Perl Inheritance Not Working as Expected
by Fletch (Bishop) on Apr 28, 2026 at 19:02 UTC

    If you check the new in the FakeTuple it's using the one arg'd version of bless which as noted in the documentation for same isn't inheritable. The constructor should be using the package used to call it and the two arg bless $ref, $class form.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      This error is just too easy to make. I used to use h2xs but it creates so much stuff that I avoid using it. I was at a Perl conference where one of the Stonehenge presenters used a 'new' tool to create classes but I forgot what it was.

      h2xs -AXn Goo Defaulting to backwards compatibility with perl 5.40.1 If you intend this module to be compatible with earlier perl versions, + please specify a minimum perl version with the -b option. Writing Goo/lib/Goo.pm Writing Goo/Makefile.PL Writing Goo/README Writing Goo/t/Goo.t Writing Goo/Changes Writing Goo/MANIFEST joel@PLANTER1 goo]$

      This does not create a 'new' boilerplate for you...

      ... our $VERSION = '0.01'; # Preloaded methods go here. ...

      Other stuff but no 'new'. A new() method in the preferred fashion would be good, no?

      Celebrate Intellectual Diversity

        Other stuff but no 'new'. A new() method in the preferred fashion would be good, no?

        No, because:

        1. Not every module is a class.
        2. Some (most?) modules which are classes use a framework which provides a standard new() in the superclass.

        If you only ever write OO modules and know that these will always have their own new() method then you can use one of the very many templating engines to write your own module creator to achieve this. I'm sure most of the existing new-project-creation tools have hooks for customisation too but I've never been bothered enough to go looking, TBH.


        🦛

        I create OO modules manually. The boilerplate is minimal. FWIW, I use module-starter --module='XXX:XXX' --builder='ExtUtils::MakeMaker' --author='XXX' --email='XXX' to start a new module and never sought any alternative.