Search code examples
perlperl-module

Perl: How can I call object methods inside END {} without warning?


package JustTesting;
use strict;
use warnings;

sub new {
    my $self = {};
    bless($self, shift);
    END { $self->goodbye() };
    return $self;
}

sub goodbye {
    print "Goodbye.\n";
}

package main;
my $this = JustTesting->new();

Output:

Variable "$self" will not stay shared at ./test line 10.
Goodbye.

Apparently it works and I can suppress the warning with no warnings inside the END block. But I wonder if there is a better way how to do this.

I tried using an anonymous sub like this:

my $cleanup = sub { $self->goodbye() };
END { $cleanup->() };

and then like this:

END { sub { $self->goodbye() }->() };

But I always get the same warning.


Solution

  • You most likely want DESTROY instead of END. See also the section on destructors in perltoot.

    package JustTesting;
    use strict;
    use warnings;
    
    sub new {
        my $self = {};
        bless($self, shift);
        return $self;
    }
    
    sub goodbye {
        print "Goodbye.\n";
    }
    
    sub DESTROY {
        my ($self) = @_;
        $self->goodbye()
    };
    
    
    package main;
    {
        say "entering scope";
        my $this = JustTesting->new();
        say "leaving scope";
    }
    say "left scope";
    

    Output:

    entering scope
    leaving scope
    Goodbye.
    left scope