I am working on some code that reads in a text file with varying formats contained in it. There are a number of sections and each section has its own format with a header followed by a number of data rows. So I created a structure like this: Section_Hash->Data_Array_of_Hashes->Hashes_Containing_Data No problem. Data::Dumper spits it back nicely. but when I try to parse it with the following code I get "Not a HASH reference" error.
# # Dump_vconfig # # Display the contents of the VConfig hashes. # # Arguments: # # Returns: noerror on success otherwise error # sub Dump_vconfig { $Data::Dumper::Indent = 3; foreach my $Section (keys(%VConfig)) { print("Section\[$Section\]\n"); foreach my $Array ($VConfig{$Section}) { foreach my $Hash (@$Array) { foreach my $Key (keys(%$Hash)) { # # This is the line that generates the Not a Hash refere +nce error # | | | | | | | | | | # V V V V V V V V V V print("Key:\[$Key\]\[$Hash->{$Key}\]\n"); } } } } return(noerror); }
I know this has got to be something stupid on my part but I can't get my brain wrapped around it today. The Full code is under the read more tags.
#!/usr/bin/perl -w use strict; use constant error => -1; use constant noerror => 0; use constant false => 0; use constant true => 1; use Data::Dumper; # # Globals # my %Config = ( name => "VConfig_Parser", vconfig_path => '/ntos/vconfig.out', ldvid => '', node_id => '', ); my %Fields = ( 'system' => ['SYSTEMNAME', 'BLKS_PER_CYLINDER'], 'clique' => ['CL_ID', 'ARRAY_COUNT'], 'node' => ['CL_ID', 'NODE_ID', 'KIND', 'SLAN', 'CLAN', 'PDN', + 'TPA_OK'], 'channel' => ['NODE_ID', 'BUS', 'SLOT', 'PORT', 'KIND', 'CUA', ' +SPEED', 'HGID', 'LCU', 'CHANNEL', 'ADDRESS'], 'lan' => ['NODE_ID', 'BUS', 'SLOT', 'PORT', 'KIND', 'HGID'], 'pdisk' => ['CL_ID', 'VDISKID', 'NBLKS', 'REDUNDANCY', 'GBID', + 'TARG', 'LUN', 'SWAP BLKS', 'PARTITION NAME', 'ARRAY'], 'vproc' => ['CL_ID', 'VPROCID', 'TYPE', 'MOVABLE', 'PMA_ID', ' +HGID', 'VDISKID', 'PID_START', 'PID_COUNT'], 'disk_name' => ['pdisk global name', 'node', 'local device', 'Curr +ent Location'], ); my %VConfig; # # Main # $0 =~ /.*\/(.*)\..*/; $0 =~ /(.*)\..*/ unless defined($1); if($#ARGV < 1 or $#ARGV > 2) { die("Usage: $1 <ldvid> <node_id> [vconfig_path]"); } else { $Config{'ldvid'} = $ARGV[0]; $Config{'node_id'} = $ARGV[1]; if (defined($ARGV[2])) { $Config{'vconfig_path'} = $ARGV[2]; } } Parse_vconfig($Config{'vconfig_path'}); print("\n"); Dump_vconfig(); exit(noerror); # # Parse_vconfig # # Read the vconfig file, splitting it's sections into hashes # # Arguments: <FileName> # # Returns: noerror on success otherwise error # sub Parse_vconfig { my $file = shift; my $Big_Array; my $fh; my $endtime; my %Tokens = ( 'system' => 'SYSTEM', 'clique' => 'CLIQUE', 'node' => 'NODE', 'channel' => 'CHANNEL', 'lan' => 'LAN', 'pdisk' => 'PDISK', 'vproc' => 'VPROC', 'disk_name' => '# Global Disk Name to Local Device Mapping', ); # # Return undef if the File Doesn't Exist or is 0 Length # if(!-s $file) { die("File:[$file] Not Found or 0 Length."); return(error); } # # Open the File - Or print Error Message if there is a problem # if(!open($fh, "<", $file)) { die("Unable to open file:[$file]:\n$^E:\n$!:\nError Number $?:$@ + "); return(error); } my $In_Section = false; my $pdisk_global_name; # # Loop through the File a Line at a time # while(<$fh>) { chomp(); my $Line = $_; my $token; my $New_Section = false; foreach (keys(%Tokens)) { $token = $_; if ($Line =~ /^$Tokens{${token}}$/) { if ($In_Section) { $VConfig{$In_Section} = $Big_Array; # print(Dumper($Big_Array)); # getc(); } $In_Section = $token; # print("Found Section:\[${token}\]\n"); $Big_Array = (); $New_Section = true; last; } } # # Skip Section Headings # if ($New_Section) { next; } my $Values; my $Record; $Values = {}; $Record = (); if ($In_Section and $In_Section ne 'disk_name' and ($Line !~ /^# +.*/)) { @$Record = split(); my $Record_Number = 0; foreach (@$Record) { # print("In_Section:\[$In_Section\] Record_Number:\[$Recor +d_Number\] \$Fields\{\$In_Section\}\[\$Record_Number\]:\[$Fields{$In_ +Section}[$Record_Number]\] \$_:\[$_\]\n"); $Values->{$Fields{$In_Section}[$Record_Number]} = $_; $Record_Number++; } } # # Different Record Format for disk_name # elsif ($In_Section eq 'disk_name') { if ($Line =~ /^# pdisk global name:.*/) { $pdisk_global_name = (split(/ /,$Line))[4]; next; } elsif ($Line =~ /^# node:/) { my $node; my $local_device; my $Current_Location_Device; ($node, $local_device, $Current_Location_Device) = (split( +/\s+/,$Line))[2,5,9]; $Values->{'pdisk global name'} = $pdisk_global_name; $Values->{'node'} = $node; $Values->{'local device'} = $local_device; $Values->{'Current Location'} = $Current_Location_Device; } else { next; } } push(@$Big_Array, \$Values); } close($fh); # Close the File When Done $VConfig{$In_Section} = $Big_Array; return(noerror); } # # Dump_vconfig # # Display the contents of the VConfig hashes. # # Arguments: # # Returns: noerror on success otherwise error # sub Dump_vconfig { $Data::Dumper::Indent = 3; foreach my $Section (keys(%VConfig)) { print("Section\[$Section\]\n"); foreach my $Array ($VConfig{$Section}) { foreach my $Hash (@$Array) { foreach my $Key (keys(%$Hash)) { print("Key:\[$Key\]\[$Hash->{$Key}\]\n"); } } } } return(noerror); } __END__

In reply to Not a HASH reference by NateTut

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.