Maze has asked for the wisdom of the Perl Monks concerning the following question:

I' writing a program that seems to die when it comes accross the following convulated code:
sub handle_direntries{ unless ($_[$#_] eq 1){ handle_direntries(handle_direntries_params(@_)); } else{ my $count = 0; my $treeref = \%::treehash; # reference to a hash while ($count != $#::path){ $treeref = \$treeref->{$::path[$count]}; $count++; next if $count == $#::path; unless (defined($treeref->{$::path[$count]})) { $treeref->{$::path[$count]} = {"$::DirLabel" => $::pat +h[$count]} } } $count = 0; while ($count != $#::direntries){ $treeref -> {$::path[$count]}{$::direntry[$count]} = "$::FileL +abel" unless $treeref -> {$::path[$count]}{$::direntry[$count]} = "$: +:DirLabel"; } } }
where it simply seems to reiterate constantly complaining about an uninitialised value at the last line..

any clues? I've been working hard on the program and I feel this is nearly working at a basic state, however this seems to stump me.
to be honest I'm probably all coded out for today

*collapses*

Replies are listed 'Best First'.
Re: uninitialised value in hash reference
by liverpole (Monsignor) on Sep 23, 2006 at 17:38 UTC
    Hi Maze,

    I don't know which value is the unitialized one (mostly because you haven't shown any code besides the subroutine to give context), but I can give you a good clue as to how to find out.

    Simply print out the variables for the line where the error is occurring.  If it's the last one, try something like:

    printf "TFD> count is '%s'\n", $count; printf "TFD> path[count] is '%s'\n", $::path[$count]; printf "TFD> direntry[count] is '%s'\n", $::direntry[$count]; printf "TFD> FileLabel is '%s'\n", $::FileLabel; printf "TFD> DirLabel is '%s'\n", $::DirLabel;

    For something like treeref which is more than a mere scalar value, you can use the module Data::Dumper, which is invaluable in these situations:

    use Data::Dumper; printf "TFD> treeref => '%s'\n", Dumper(\$treeref);

    That should tell you pretty quickly if you have an undefined value, and exactly which it is.

    Update:  I should have mentioned that I use the string "TFD" to mean "Temporary - for debug".  It's an easy way to add debugging information that can later be searched for and removed.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: uninitialised value in hash reference
by rodion (Chaplain) on Sep 23, 2006 at 17:51 UTC
    As I read this sub, the first thing you do is call the same sub recursively, with exactly the same argurmen list, unless the last element's equal to one.

    I assume you meant to pull one element off the front or back of the @_ parameter array and work recursively on the remainder, but the pulling off part got forgotten. Filling up the stack can lead to strange errors, so you should fix that first.

      There's a subroutine call in there, that presumably does the @_ manipulations necessary:
      unless ($_[$#_] eq 1){ handle_direntries(handle_direntries_params(@_)); }
      But since the poster didn't give us the code for handle_direntries_params(), we can only assume that it at least doesn't return @_ unchanged.
Re: uninitialised value in hash reference
by Maze (Sexton) on Sep 27, 2006 at 21:04 UTC

    Well i'm feeling more refreshed now

    hhmmm - yes I do appear to have ommited some essential code, well that was a mistake, I decided not to put the entire program up in the first place as it is monstrous and I want to focus on the problem at hand rather than the general mess of my code, it's just about working at least.

    I've done some debugging, as well as rewrote that bit so to avoid the nasty unless and recursive statement, and in fact the problem with uninitialised values is nothing to do with the code that I posted *oops* it was in fact an upstream subroutine, getting stuck on the /. and /.. entries in a directory no less.

    My problem at the moment seems to be perl complaining about using a hash as a reference being deprecated, the issue is this particular line "$treeref = \%$treeref->{$::path$count};" (changed since the posting) it's there in order for the program to keep track of where it's got to in the particular tree. But perl seems to refuse me doing it, it probably has it's reasons. But I now have to think someway around it...

    I am considering recoding the entire program, I put it together without really thinking, if people would like to have a look at it, then they can have a look at it on the code section.

    it's suppsed to scan an entire filesystem, and return an XML file recording it's structure, but it's proving more difficult than I thought

    Don't suppose anyone here has any hints?