Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing branch assignment in Perl for SUPER:: methods

I am about to finish to study the Intermediate Perl book.

In chapter 18 Object Destruction is introduced the following DESTROY method definition:

# lib/Animal.pm
package Animal {
  # ...
  sub DESTROY {
    my $self = shift;
    if ($self->{temp_filename}){
      my $fh = $self->{temp_fh};
      close $fh;
      unlink $self->{temp_filename};
    }
    print '[', $self->name, " has died.]\n";
  }
# ...
}

# lib/Horse.pm
package Horse {
  use parent qw(Animal)
  # ...
  sub DESTROY {
    my $self = shift;
    $self->SUPER::DESTROY if $self->can( 'SUPER::DESTROY' );
    print "[", $self->name, " has gone off to the glue factory.]\n";
  }
# ...
}

After a few unsuccessfully attempt, I wrote this test based on this answer:

# t/Horse.t
#!perl -T

use strict;
use warnings;
use Test::More tests => 6;
use Test::Output;
# some other tests

# test DESTROY() when SUPER::DESTROY is not defined;
{
  my $tv_horse = Horse->named('Mr. Ed');
  stdout_is( sub { $tv_horse->DESTROY }, "[Mr. Ed has died.]\n[Mr. Ed has gone off to the glue factory.]\n",
      'Horse DESTROY() when SUPER::DESTROY is defined');
}

{
  my $tv_horse = Horse->named('Mr. Ed');
  sub Animal::DESTROY { undef }
  stdout_is( sub { $tv_horse->DESTROY }, "[Mr. Ed has gone off to the glue factory.]\n",
      'Horse DESTROY() when SUPER::DESTROY is not defined');
}

I cannot test the output correctly for both cases since the method redefinition sub Animal::DESTROY { undef } is affecting also the test in the previous block.

Do you know any way to ensure the method redefinition to work as expected?

Thanks

like image 585
mabe02 Avatar asked Mar 08 '23 05:03

mabe02


1 Answers

This should set removed/redefined subroutine only until the end of enclosing block,

{
  # not needed when removing method
  # no warnings 'redefine';

  my $tv_horse = Horse->named('Mr. Ed');
  # returns undef
  # local *Animal::DESTROY = sub { undef };

  # remove the mothod until end of the enclosing block
  local *Animal::DESTROY;

  # ..
}
like image 57
mpapec Avatar answered Mar 16 '23 15:03

mpapec