Perl:使用Moose进行递归对象实例化

时间:2017-05-19 08:05:54

标签: perl recursion moose

在下面的示例代码中,我定义了一个可以具有相同类的子对象的类Person

当我调用printTree方法时,我期待以下输出

Sam    Ram    Geeta

我所看到的是

SamRamRamRamRamRamRamRamRamRamRamR.....

关于我做错了什么以及如何实现目标的任何提示?

package Person;

use Moose;

has name => ( is => 'ro' );

my @kids;

sub addChild {
    my ( $self, $name ) = @_;
    my $k = Person->new( name => $name );
    push @kids, $k;
    return $k;
}

sub printTree {
    my $self = shift;
    print $self->name;
    $_->printTree foreach ( @kids );
}



no Moose;

package main;

my $s = Person->new( name => "Sam" );
my $r = $s->addChild( "Ram" );
my $g = $s->addChild( "Geeta" );

$s->printTree;

1 个答案:

答案 0 :(得分:6)

问题是@Person::kids不属于任何一个实例,并且您最终会以

结尾
@Person::kids = ($r, $g);
$s->printTree() loops through @Person::kids, calls
 $r->printTree() loops through @Person::kids, calls
  $r->printTree() loops through @Person::kids, calls
   $r->printTree() loops through @Person::kids, calls
    ...

您需要将其设为属性,例如

has kids => (
    isa => 'ArrayRef[Person]',
    traits => ['Array'],
    handles => {
        all_kids => 'elements',
        push_kids => 'push',
    },
    default => sub { [] },
);
sub addChild {
    my ($self, $name) = @_;
    my $k = Person->new(name => $name);
    $self->push_kids($k);
    return $k;
}
sub printTree {
    my ($self) = @_;
    print $self->name;
    $_->printTree foreach $self->all_kids;
}

您可以从Array特征检查perldoc Moose::Meta::Attribute::Native::Trait::Array其他有用的句柄。