Subject: | Circular reference |
Hi,
The following code consumes memory indefinitely:
--
use mxtrp;
my $mxtrp = mxtrp->new;
while (1) {
my $obj = $mxtrp -> get_obj;
}
--
$ while ps -C perl -o rss=; do sleep 1; done
18160
29216
39992
49448
54036
60220
71016
79704
84264
91220
101932
--
moreover, Devel::Cycle::find_cycle($obj) complains:
--
Cycle (1):
$Class::MOP::Class::__ANON__::SERIAL::2::A->{'__MOP__'} =>
\%Moose::Meta::Class::B
$Moose::Meta::Class::B->{'roles'} => \@C
$C->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterized::D
$MooseX::Role::Parameterized::Meta::Role::Parameterized::D->{'parameters'}
=> \%Class::MOP::Class::__ANON__::SERIAL::1::E
$Class::MOP::Class::__ANON__::SERIAL::1::E->{'__MOP__'} =>
\%Moose::Meta::Class::F
$Moose::Meta::Class::F->{'_meta_instance'} =>
\%Moose::Meta::Instance::G
$Moose::Meta::Instance::G->{'attributes'} => \@H
$H->[0] =>
\%MooseX::Role::Parameterized::Meta::Parameter::I
$MooseX::Role::Parameterized::Meta::Parameter::I->{'associated_methods'}
=> \@J
$J->[0] => \%Moose::Meta::Method::Accessor::K
$Moose::Meta::Method::Accessor::K->{'body'} => \&L
$L variable $meta => \$M
$$M => \%Moose::Meta::Method::Accessor::K
Cycle (2):
$Class::MOP::Class::__ANON__::SERIAL::2::A->{'__MOP__'} =>
\%Moose::Meta::Class::B
$Moose::Meta::Class::B->{'roles'} => \@C
$C->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterized::D
$MooseX::Role::Parameterized::Meta::Role::Parameterized::D->{'parameters'}
=> \%Class::MOP::Class::__ANON__::SERIAL::1::E
$Class::MOP::Class::__ANON__::SERIAL::1::E->{'__MOP__'} =>
\%Moose::Meta::Class::F
$Moose::Meta::Class::F->{'attributes'} => \%N
$N->{'fields'} =>
\%MooseX::Role::Parameterized::Meta::Parameter::I
$MooseX::Role::Parameterized::Meta::Parameter::I->{'associated_methods'}
=> \@J
$J->[0] => \%Moose::Meta::Method::Accessor::K
$Moose::Meta::Method::Accessor::K->{'body'} => \&L
$L variable $meta => \$M
$$M => \%Moose::Meta::Method::Accessor::K
Cycle (3):
$Class::MOP::Class::__ANON__::SERIAL::2::A->{'__MOP__'} =>
\%Moose::Meta::Class::B
$Moose::Meta::Class::B->{'roles'} => \@C
$C->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterized::D
$MooseX::Role::Parameterized::Meta::Role::Parameterized::D->{'parameters'}
=> \%Class::MOP::Class::__ANON__::SERIAL::1::E
$Class::MOP::Class::__ANON__::SERIAL::1::E->{'__MOP__'} =>
\%Moose::Meta::Class::F
$Moose::Meta::Class::F->{'methods'} => \%O
$O->{'fields'} => \%Moose::Meta::Method::Accessor::K
$Moose::Meta::Method::Accessor::K->{'body'} => \&L
$L variable $meta => \$M
$$M => \%Moose::Meta::Method::Accessor::K
Cycle (4):
$Class::MOP::Class::__ANON__::SERIAL::2::A->{'__MOP__'} =>
\%Moose::Meta::Class::B
$Moose::Meta::Class::B->{'roles'} => \@C
$C->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterized::D
$MooseX::Role::Parameterized::Meta::Role::Parameterized::D->{'roles'} =>
\@P
$P->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterizable::Q
$MooseX::Role::Parameterized::Meta::Role::Parameterizable::Q->{'parameters_metaclass'}
=> \%Moose::Meta::Class::F
$Moose::Meta::Class::F->{'_meta_instance'} =>
\%Moose::Meta::Instance::G
$Moose::Meta::Instance::G->{'attributes'} => \@H
$H->[0] =>
\%MooseX::Role::Parameterized::Meta::Parameter::I
$MooseX::Role::Parameterized::Meta::Parameter::I->{'associated_methods'}
=> \@J
$J->[0] => \%Moose::Meta::Method::Accessor::K
$Moose::Meta::Method::Accessor::K->{'body'} => \&L
$L variable $meta => \$M
$$M => \%Moose::Meta::Method::Accessor::K
Cycle (5):
$Class::MOP::Class::__ANON__::SERIAL::2::A->{'__MOP__'} =>
\%Moose::Meta::Class::B
$Moose::Meta::Class::B->{'roles'} => \@C
$C->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterized::D
$MooseX::Role::Parameterized::Meta::Role::Parameterized::D->{'roles'} =>
\@P
$P->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterizable::Q
$MooseX::Role::Parameterized::Meta::Role::Parameterizable::Q->{'parameters_metaclass'}
=> \%Moose::Meta::Class::F
$Moose::Meta::Class::F->{'attributes'} => \%N
$N->{'fields'} =>
\%MooseX::Role::Parameterized::Meta::Parameter::I
$MooseX::Role::Parameterized::Meta::Parameter::I->{'associated_methods'}
=> \@J
$J->[0] => \%Moose::Meta::Method::Accessor::K
$Moose::Meta::Method::Accessor::K->{'body'} => \&L
$L variable $meta => \$M
$$M => \%Moose::Meta::Method::Accessor::K
Cycle (6):
$Class::MOP::Class::__ANON__::SERIAL::2::A->{'__MOP__'} =>
\%Moose::Meta::Class::B
$Moose::Meta::Class::B->{'roles'} => \@C
$C->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterized::D
$MooseX::Role::Parameterized::Meta::Role::Parameterized::D->{'roles'} =>
\@P
$P->[0] =>
\%MooseX::Role::Parameterized::Meta::Role::Parameterizable::Q
$MooseX::Role::Parameterized::Meta::Role::Parameterizable::Q->{'parameters_metaclass'}
=> \%Moose::Meta::Class::F
$Moose::Meta::Class::F->{'methods'} => \%O
$O->{'fields'} => \%Moose::Meta::Method::Accessor::K
$Moose::Meta::Method::Accessor::K->{'body'} => \&L
$L variable $meta => \$M
$$M => \%Moose::Meta::Method::Accessor::K
--
Subject: | mxtrp.pm |
package mxtrp;
use Moose;
sub get_obj {
my $self = shift;
my $traits = [ "mxtrp::paramrole" => { fields => [qw/foo bar/] } ];
my $obj = mxtrp::obj -> new_with_traits(
traits => $traits,
);
}
1;
package mxtrp::obj;
use Moose;
with 'MooseX::Traits';
sub get_field {
my ($self, $field) = @_;
return $field;
}
1;
package mxtrp::paramrole;
use MooseX::Role::Parameterized;
parameter 'fields' => (
is => 'ro',
isa => 'ArrayRef',
default => sub {[]},
);
role {
my $self = shift;
my @fields = @{$self -> fields};
@fields = qw(foo bar) unless scalar @fields;
for my $handle (@fields) {
method $handle => sub {
my $self = shift;
$self -> get_field($handle, @_);
}
}
};
1;