Переписать рекурсивную функцию в perl, чтобы ее можно было использовать в контексте списка - PullRequest
3 голосов
/ 09 марта 2011

Рассмотрим двоичное дерево, разработанное в Moose :: Cookbook :: Basics :: Recipe3

Чтобы извлечь все узлы в предзаказе , я мог бы добавить следующую подпрограммув пакет BinaryTree

sub pre_order {
  my ($self,$aref) = @_;

  push @$aref, $self->node;

  pre_order($self->left,$aref) if $self->has_left;
  pre_order($self->right,$aref) if $self->has_right;
}

Подпрограмма должна использоваться следующим образом:

my $btree = BinaryTree->new;
#add some nodes

#then later...
my @nodes_in_preorder;
$btree->pre_order(\@nodes_in_preorder);

Как мне изменить подпрограмму, чтобы иметь возможность использовать синтаксис, подобный приведенному ниже:

my @nodes_in_preorder = $btree->pre_order();

для того, чтобы иметь возможность делать что-то вроде

for ($btree->pre_order()) { #bla bla } 

позже.

Имеет ли это смысл, или я занимаюсь педантизмом?

Ответы [ 2 ]

9 голосов
/ 09 марта 2011

Как насчет:

sub pre_order {
  my $self = shift;
  return ($self->node,
    $self->has_left ? $self->left->pre_order : (),
    $self->has_right ? $self->right->pre_order : ());
}
0 голосов
/ 10 марта 2011

Вы можете просто сменить абонента:

for ( do { my @preorder; $btree->pre_order(\@preorder); @preorder } ) {

Или просто измените код следующим образом:

sub pre_order {
    my ($self,$aref) = @_;

    push @$aref, $self->node;

    $self->left->pre_order($aref) if $self->has_left;
    $self->right->pre_order($aref) if $self->has_right;

    return @$aref if wantarray;
}

Нет необходимости передавать ссылку на массив во внешний вызов; один будет создан автоматически, поэтому ваш код будет просто работать (TM):

for ( $self->pre_order() ) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...