Rewriting a recursive function in perl so that it can be used in list context
Consider the binary tree developed in Moose::Cookbook::Basics::Recipe3
To retrieve all nodes in preorder, I could add the following subroutine to the BinaryTree package
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;
}
The sub would have to be used like this:
my $btree = BinaryTree->new;
#add some nodes
#then later...
my @nodes_in_preorder;
$btree->pre_order(\@nodes_in_preorder);
How would i have to change the subroutine to be able to use syntax like the below:
my @nodes_in_preorder = $btree->pre_order();
in order to be able to do things like
for ($btree->pre_order()) { #bla bla }
later on.
Does this make sense, or am I being to pedantic?
How about:
sub pre_order {
my $self = shift;
return ($self->node,
$self->has_left ? $self->left->pre_order : (),
$self->has_right ? $self->right->pre_order : ());
}
You could just change the caller:
for ( do { my @preorder; $btree->pre_order(\@preorder); @preorder } ) {
Or simply change the code like so:
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;
}
No need to pass an array reference to the outer call; one will be created automatically, so your code will Just Work (TM):
for ( $self->pre_order() ) {
精彩评论