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

I'm getting errors in a perl script that requires an xml input file. I keep getting the following error: main::running uncatalog for dcs entries /uncatalog.pl failed: Please investigate ] STDERR : [Not a HASH reference at /uncatalog.pl line 56. The code it is referencing is listed below, lines 51 through 67

51 # Iterate over the configuration types listed in @type_ord +er 52 foreach my $type (@type_order) { 53 print "$log_pre running $action for $type entries\ +n"; 54 # Iterate over all items of that type 55 my $type_hash = $hashref->{$type}; + #shortcut to smaller hash 56 foreach my $item (keys %{$type_hash}) { 57 print "$log_pre running $action for $type +$item\n"; 58 my $item_hash = $type_hash->{$item}; + #shortcut to smaller hash 59 #Add values for type and action into the h +ash 60 $item_hash->{'name'} = $item; 61 $item_hash->{'type'} = $type; 62 $item_hash->{'action'} = $action; 63 #print Dumper($item_hash); 64 #execute action for the individual configu +ration 65 unless (db2_mgmt_cat(\%{$item_hash})) { 66 #unless (db2_mgmt_cat(\%{$type_hash})) { 67 # Return false if the action could + not be completed successfully.

Replies are listed 'Best First'.
Re: Not a HASH reference error
by perlfan (Parson) on Feb 24, 2016 at 20:07 UTC
    In line 55, my $type_hash = $hashref->{$type};, you are not checking to make sure that $hashref->{$type} exists as an entry or that what's in there is a hash reference.

    The answer to you question would be more clear if we knew what $hashref looks like and the value of $type when it fails.

      Okay, I can go ahead and find that, but it is failing at line 56, not 55. Is that significant? Thank you for the reply.

        The significance is that line 56 is the earliest point at which Perl discovers there's a problem with line 55.

        Line 55 grabs the value of a hash key. In this case, that hash key does not contain a hash reference (maybe doesn't exist at all). But this is no problem for Perl. If the key doesn't exist, then the value is undef. If it exists but isn't a hash reference, it still causes no problem for line 55. In line 56 you then try to dereference that value as though it were a hash. If the value was undef, that clearly cannot be dereferenced. And if the value was defined, but wasn't a hash ref, you also cannot dereference it as a hash. So at this point Perl has no idea what to do, and complains.


        Dave

Re: Not a HASH reference error
by mhearse (Chaplain) on Feb 24, 2016 at 20:33 UTC
    Try dumping your hashref. It may not be what you think it is:
    use Data::Dumper; print Dumper($hashref);

      Okay, where should I put that? Should that be at the top of the perl script or in lines 41 or 55? Thanks

        Actually I think I got it. Here is the output:

        /www/configs/DB2/HLBROKDB/scripts/ScriptConfig.Driver.sh /www/configs/ +DB2/HLBROKDB/config/ScriptConfig.HLBROKDB-PROD.xml prodwxbat204as1l Remove control-Ms from config script /www/configs/DB2/HLBROKDB/config/ +ScriptConfig.HLBROKDB-PROD.xml ... Uncataloging items in /www/configs/DB2/HLBROKDB/config/ScriptConfig.HL +BROKDB-PROD.xml main::awc_db2_mgmt_kick running uncatalog for dcs entries $VAR1 = { 'db' => { 'HLBROKDB' => { 'node' => 'HLBROKDB' } }, 'dcs' => [ {} ], 'node' => { 'HLBROKDB' => { 'server' => 'produdbhlbrokdb', 'port' => '54042' } }, 'changeLog' => [ 'Created by Praveenkumar Sampath on 2015-01- +06 05:05:59' ] }; Not a HASH reference at /www/was50/bin/awc_db2_mgmt.pl line 58. /www/was50/bin/awc_db2_mgmt.pl failed: Please investigate.
        47 # OUTPUT returns true/false that the specified db2 configuration f +ile could be processed appropriately for the given action. 48 my $log_pre = whatsub(); 49 my ($action,$hashref,@type_order) = @_ or (warn "$log_pre +Invalid arguments" and return 0); 50 51 # Iterate over the configuration types listed in @type_ord +er 52 foreach my $type (@type_order) { 53 print "$log_pre running $action for $type entries\ +n"; 54 # Iterate over all items of that type 55 use Data::Dumper; 56 print Dumper($hashref); 57 my $type_hash = $hashref->{$type}; + #shortcut to smaller hash 58 foreach my $item (keys %{$type_hash}) { 59 print "$log_pre running $action for $type +$item\n"; 60 my $item_hash = $type_hash->{$item}; + #shortcut to smaller hash 61 #Add values for type and action into the h +ash 62 $item_hash->{'name'} = $item; 63 $item_hash->{'type'} = $type; 64 $item_hash->{'action'} = $action; 65 print Dumper($hashref); 66 #execute action for the individual configu +ration 67 unless (db2_mgmt_cat(\%{$item_hash})) { 68 #unless (db2_mgmt_cat(\%{$type_hash})) { 69 # Return false if the action could + not be completed successfully.

      Okay, so latest on this saga. I found out that on an older version of Linux running an older version of perl (v5.8.8), I get a warning but the command still executes: Pseudo-hashes are deprecated at /www/was50/bin/awc_db2_mgmt.pl line 56. Now, on a more recent version of Linux running a newer version of perl (v5.10.1), this just blows up. No warning, just errors out. UGGGH HELP!!!

        If you know the pseudo-hashes are empty of data then a simple check and skip might suffice

        foreach my $type (@type_order) { print "$log_pre running $action for $type entries\n"; # Iterate over all items of that type my $type_hash = $hashref->{$type}; next unless ref($type_hash) eq 'HASH'; # <-- add

        If you are not sure then use

        foreach my $type (@type_order) { # Iterate over all items of that type my $type_hash = $hashref->{$type}; if ( (ref($type_hash) eq 'ARRAY') && (@$type_hash<2) ){ print "Skipping empty pseudo-hash for $type entries\n"; next; } else { print "$log_pre running $action for $type entries\n"; } . .
        poj
Re: Not a HASH reference error
by Your Mother (Archbishop) on Feb 26, 2016 at 19:26 UTC

    Sounds to me like you are using XML::Simple and the XML stopped coming exactly as originally expected so the data structures changed type. If so, search around in here or maybe show the invocation for XMLin or however you are using it.

      Yes, we are using XML::Simple. I appreciate the feedback, I'll dig into that a little more. Thank you.