sub _build { my ($self, $file) = @_; croak "Unable to retrieve data" unless open(INPUT,$file); # You just stomped on the global $_. You have to either assign it # to a pad variable (like I did here) or local $_ first. Just a # plain while() is dangerous. while (my $line = ) { # You didn't pick named variables. Variables should have meaningful # names so you don't have to guess at what $field[2] is later in # the code. my ($id, $parent_id, $title) = split ' ', $line; unless ( $id =~ /^\d+$/ and $parent_id =~ /^\d+$/ ) { carp "Unable to parse\n$line"; next; } # You were assigning the id to descendants. That should be stored # separately. Also, you used the hash keys of the object for the # node titles but also expect the 'decendents' key to remain unused. # You should keep that separate somewhere. $self->{'title2id_dict'}{$title} = $id; # Shall we assume the IDs all start low and go up? You'll consume # much memory if an ID comes in like 1000000. I compensate for that # and just use a hash. push @{$self->{'descendants'}{$parent_id}}, $id; } }