use strict; use warnings; use Devel::Cycle; package A; sub new { my ($class, $href) = @_; my $self = { dbi => $$href{dbi} }; $self->{helper_child} = Helper->new( parent => $self, helper_function => sub { my $parent = shift; $parent->this_is_in_A(@_); }, ); bless $self, $class; } sub do_something { my $self = shift; $self->{helper_child}->do_helper(); } sub this_is_in_A { my ($self, $arg) = @_; print "this_is_in_A, arg: $arg, dbi is $self->{dbi}\n"; } sub DESTROY { print shift."->DESTROY\n" } package Helper; use Scalar::Util qw/weaken/; sub new { my $class = shift; my $self = { @_ }; weaken( $self->{parent} ); bless $self, $class; } sub do_helper { my $self = shift; $self->{helper_function}->($self->{parent}, "param from Helper"); } sub DESTROY { print shift."->DESTROY\n" } package main; my $x = A->new( { dbi => "some dbi object" } ); $x->do_something(); $x->do_something(); find_cycle($x); print "undef'ing \$x\n"; $x = undef; print "End\n"; __END__ this_is_in_A, arg: param from Helper, dbi is some dbi object this_is_in_A, arg: param from Helper, dbi is some dbi object undef'ing $x A=HASH(0x55e36742fc88)->DESTROY Helper=HASH(0x55e36742fdc0)->DESTROY End