in reply to Re^2: Avoiding circular references
in thread Avoiding circular references

So you pass $dbi as an argument.

package A; sub new { my ( $class, $href ) = @_; my $self = { dbi => $$href{dbi} }; $self->{helper} = Helper->new( helper_function => sub { my $dbi = $$href{dbi}; return $self->this_is_from_A($dbi, @_); # p +ass $dbi } ); bless $self, $class; } sub do_something { my $self = shift; $self->{helper}->called_from_helper(); } sub this_is_from_A { my ($self, $dbi, $arg) = @_; # r +eceive $dbi print "$arg\nthis_is_from_A using $dbi\n"; }

Replies are listed 'Best First'.
Re^4: Avoiding circular references
by frazap (Monk) on Dec 06, 2019 at 15:16 UTC

    Thanks !

    but that still make a circular reference because of $self

    This works

    use strict; use warnings; use Devel::Cycle; package A; sub new { my ( $class, $href ) = @_; my $self = { dbi => $$href{dbi} }; $self->{helper} = Helper->new( helper_function => sub { &this_is_from_A( $$href{dbi}, @_) } ); bless $self, $class; } sub do_something { my $self = shift; $self->{helper}->called_from_helper(); } sub this_is_from_A { my ($dbi, $arg) = @_; print "$arg\nthis_is_from_A using $dbi\n"; } package Helper; sub new { my $class = shift; my %def = ( a => "something"); my %arg = ( ref $_[0] eq "HASH" ? ( %def, %{ $_[0] } ) : ( %def, + @_ ) ); my $self = \%arg; bless $self, $class; } sub called_from_helper { my $self = shift; print "called_from_helper\n"; $self->{helper_function}->("param from Helper"); } package main; my $a = A->new( { dbi => "some dbi object" } ); $a->do_something(); $a->do_something(); find_cycle($a);
      but that still make a circular reference because of $self

      You could stick close to your original solution with a method call if you pass a weakened copy of $self to the subroutine reference:

      use strict; use warnings; use Devel::Cycle; package A; use Scalar::Util qw/weaken/; sub new { my ( $class, $href ) = @_; my $self = { dbi => $$href{dbi} }; my $weak_self = $self; weaken $weak_self; $self->{helper} = Helper->new( helper_function => sub { $weak_self->this_is_from +_A(@_) } ); bless $self, $class; } # ....the rest remains unchanged.
      That way, this_is_from_A has full access to the $self object (which isn't needed in your example so far).