in reply to Re: Code Review (recursive data structure)
in thread Code Review (recursive data structure)

diotalevi, Thanks - let me work through your points:
  • Returning string instead of @descendants is un-perlish
         Agreed. Because the desired output was a string I encorporated that into the module. It would have been better i guess to show the usage as print (join ',' $family_tree->get_decendents('dog')) , "\n"; and just returned @descendants
  • Your solution was nice
         But it didn't meet Isanchez's requirements about being a single line of output starting at an arbitrary point.
  • Infinite loop
         yes, if a node has a pointer to a child that is actually a parent - it will cause an infinite loop. That was one of the things I was working on when I decided it was just "yucky" code.
  • equivalent of symbolic references
         I don't understand this statement
  • Better variable names
         Could not agree more
  • My use of key assignment
         I disagree with your synopsis of what I did (but could very will just be misunderstanding you). I did not assign the id to the decendents, it is the array index where the decendents can be found. As far as the possibility that I may step on myself if I get a title that is 'decendents' (I think that is what you meant) - I could move it to a private base key.
  • hash "index" versus array for memory purposes
         I agree
  • I will have to fix get_decendents myself
         This is the piece of code I was hoping to get help on :-)

    How does this look like for an update?

    package Isanchez; use strict; use Carp; our $VERSION = '0.01'; sub new { my ($class, $file) = @_; my $self = bless {}, $class; $self->_build($file); return $self; } sub _build { my ($self, $file) = @_; croak "Unable to retrieve data" unless open(INPUT,$file); while (my $line = <INPUT>) { chomp $line; my($id, $parent_id, $title) = split /\s+/ , $line, 3; unless ($title && $id =~ /^\d+$/ && $parent_id =~ /^\d+/ && $p +arent_id < $id) { carp "Unable to parse\n$line"; next; } $self->{$title}{decendent} = $id; push @{$self->{decendents}{$parent_id}}, $title; } } sub get_decendents { my ($self, $origin) = @_; croak "You must enter an origin in the tree" unless $origin; croak "$origin can not be found" unless exists $self->{$origin}; my $index = $self->{$origin}{decendent}; my @list = @{$self->{decendents}{$index}} if exists $self->{decend +ents}{$index}; return $origin unless @list; my @decendents = ($origin); while (@list) { my $decendent = shift @list; push @decendents, $decendent; my $index = $self->{$decendent}{decendent}; push @list, @{$self->{decendents}{$index}} if exists $self->{d +ecendents}{$index}; } return @decendents; }

    Cheers - L~R