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

I have code to build a hash of array references. It seems that when I add the array reference to the hash, it does not always update the number of elements in the hash correctly. I can make this same kind of call again and it seems to add in the array refernce. Does anyone know of an issue with adding array references to a hash. My code snippet is as follows:
foreach $key (keys %extractDataFunctionHash) { # Loop over the data in each lines array and extract the specifi +c # data for that sample. Call the function defined for that key. # #printf("calling has function: %s\n", $key); $extractDataFunctionHash{$key}($key, $DNRef, $EDHRef); $numInHash = %$EDHRef; printf("\nPASS: Data extraction complete for %s...%d items in ha +sh.\n", $key, $numInHash); }
The function references in the function hash each do basically the same work other than some simple formatting differences. Each one at the end of its array data collection/creation has the following statement:
$EDHRef->{$key} = \@extractedLinesArray;
When I print out the number of elements in the hash each time in the loop it indicates 1 element, then 1 element, then 2, then 3, then 4, then 5. There should be 6 elements in the hash. I have put printfs all around this line of code. The first function (there are 6 calls to 6 difference functions in the function hash) call adds 1 element in the hash and the number in hash (1) is correct. On the second call, it indicates there is only 1 element in the hash again. Afterwards it increments as it should up to 5 instead of 6. I am totally confused and need help. thanks...

Replies are listed 'Best First'.
Re: hashes of array references
by davorg (Chancellor) on Jul 22, 2009 at 19:19 UTC
    $numInHash = %$EDHRef;

    This isn't doing what you think it is. Evaluating a hash in scalar context is rarely useful. They don't work the same way as arrays.

    What you really want is to call keys in scalar context. That will give you the number of keys in the hash.

    $numInHash = keys %$EDHRef;

    See the Copyright notice on my home node.

    Perl training courses

      You are the Perl God....that was exactly my problem. Actually the code worked fine. I was just obtaining the number of elements wrong. Thank you very much.
Re: hashes of array references
by moritz (Cardinal) on Jul 22, 2009 at 19:23 UTC
    It would help if you gave us a small, working example that we can actually run and debug.

    But it might be easier if the functions wouldn't assign stuff to a hash ref, but return a value, which the caller can then assign, ie you write something along these lines:

    $EDHRef->{$key} = extractDataFunctionHash{$key}->($key, $DNRef);

    That way it's much simpler to debug.

    One (possibly unrelated) thing to be aware of is this: $EDHRef->{$key} = \@extractedLinesArray; If @extractedLinesArray is not locally scoped to the current sub, it will always assign a reference to the same array, so all the values in %$EDHRef will end up being the same array.

      Thanks for the reply....Good idea...actually I'm passing the hashes around from a main driver via a reference. I declare them locally and pass the reference through the different menu selections. All this does is crunch data files and is written very specific to the task in mind. I'm going to try the comment from the first reply and see if that makes a diference. If that fails I'll post the code and a set of data files.