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

Perl:使用Moose进行递归对象实例化,perl,recursion,moose,Perl,Recursion,Moose,在下面的示例代码中,我定义了一个类Person,它可以具有相同类的子对象 当我调用printree方法时,我希望得到以下输出 山姆·拉姆·吉塔 相反,我看到的是 samramr。。。。。 关于我做错了什么以及如何实现我的目标,有什么提示吗 包人; 使用驼鹿; has name=>(is=>'ro'); 我的孩子们; 子addChild{ 我的($self,$name)=@; my$k=Person->new(name=>$name); 推送@kids,$k; 返回$k; } 子打印树{ 我的

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

当我调用
printree
方法时,我希望得到以下输出

山姆·拉姆·吉塔 相反,我看到的是

samramr。。。。。
关于我做错了什么以及如何实现我的目标,有什么提示吗

包人;
使用驼鹿;
has name=>(is=>'ro');
我的孩子们;
子addChild{
我的($self,$name)=@;
my$k=Person->new(name=>$name);
推送@kids,$k;
返回$k;
}
子打印树{
我的$self=shift;
打印$self->name;
$\uUx->printTree foreach(@kids);
}
没有驼鹿;
主包装;
我的$s=Person->new(name=>“Sam”);
my$r=$s->addChild(“Ram”);
my$g=$s->addChild(“Geeta”);
$s->printTree;

问题在于
@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;
}

您可以从
数组
trait中检查其他有用的句柄。

问题是
@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;
}

您可以从
数组
特征中检查其他有用的句柄。

不要在
打印树
内部调用
打印树
。顺便说一句,
@kids
不也应该是一个属性吗?你的
@kids
在类中是一个独生子女。这意味着所有对象都共享它。这是个坏主意。它应该是一个财产。我稍后会写一个答案。不要在
printree
内调用
printree
。顺便说一句,
@kids
不也应该是一个属性吗?你的
@kids
在类中是一个独生子女。这意味着所有对象都共享它。这是个坏主意。它应该是一个财产。我稍后会写一个答案。