On Aug 7, 7:59 am, [EMAIL PROTECTED] (Charles J Gillan) wrote:
> I have a problem with extracting an individual hash from an array of
> hashes. I can't work out, or find elsewhere, the syntax for this.

The syntax is found in
perldoc perlref
perldoc perlreftut
perldoc perllol
and
perldoc perldsc


> Code as follows:
>
>      devices_array_oH  is set up as array of hashes

No.  There is no such variable.  Variables in Perl start with $, @, %,
&, or *.  Perhaps '@devices_array_oH' is an array of hashes?

> I want to loop over all hashes in the array and to print the key value pairs 
> for
> each hash.
>
> I have tried the following but get run-time errors:
>
> my($num_devices, $idevice);
>
> $num_devices = scalar (@devices_array_oH) ;
> for ($idevice=0; $idevice < $num_devices; $idevice++)

These two lines are almost certainly better written:

for my $idevice (0 .. $#devices_array_oH) {

>   {
>    my (%device_hash, $itemp, $key);
>
>    $itemp = $idevice + 1;
>
>    #
>    #--- Extract one element of array to local hash
>    #
>
>    %device_hash = $devices_array_oH[$idevice];  
>     <-----------   Flagged as run-time error:

No.  Flagged as run-time warning.  Very different.

>     Reference found where even size list expected

And did you look up that warning message to see what it means?

perldoc perldiag
     Reference found where even-sized list expected
         (W misc) You gave a single reference where Perl was
         expecting a list with an even number of elements (for
         assignment to a hash).

So this is telling you that $devices_array_oH[$idevice] is a
reference, and you're trying to use it as a hash.  You can't do that.
You can either assign that reference to a new scalar variable, or you
can dereference the reference and assign the resulting hash to a hash
variable:

my $device_hash_ref = $devices_array_oH[$idevice];
or
my %device_hash = %{$device_array_oH[$idevice]};

>    print "     Details of device $itemp: ";
>    print "\n\n";
>
>    foreach $key (keys(%device_hash))
>      {
>       print ("       $key  \t  $device_hash{$key} \n");    
>      <---- Flagged as run-time error

Again.  Warning.  Not Error.  Errors cause your program to stop.
Warnings are Perl's way of telling you "this is probably not what you
meant to do."

>      use of un-initialized value in concatenation
>      Presumably due to above

Yes.  Because you created a hash that has only one key-value pair.
The key is the stringified-form of that reference, and its value is
undef.

>      }
>
>    print "\n\n";
>    print "     ***** End of details for all devices ";
>    print "\n\n";
>   }
>
> Just can't figure it out - any suggestions.

I would have written the program like this:

my $itemp = 1;
foreach my $device_hash_ref (@devices_array_oH) {

   print "     Details of device $itemp: ";
   print "\n\n";

   foreach my $key (keys %{$device_hash_ref})
   {
      print ("       $key  \t  $device_hash{$key} \n");
   }
   $itemp++;
}

There is rarely a need to use C-style for loops, or to access arrays
via indices.  Just use a foreach loop and get access to their contents
(in this case, the references to hashes) directly.

Your main issue, I believe, is thinking that arrays can contain
hashes.  They cannot.  They can only contain *references* to hashes.
Therefore, when you get an element of one of these arrays, you get a
reference to a hash, not an actual hash.  That reference must be
dereferenced in order to use it.

Please, do read those perldocs I referred you to earlier.

Paul Lalli


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to