What causes this bizarre hash behavior? 
Author Message
 What causes this bizarre hash behavior?

Running the following program produces something that I don't quite
understand:

#!/usr/local/bin/perl -w

use Data::Dumper;

# List of known IDs
%myHash = ();
$myHash{'41889'} = 1;
$myHash{'41890'} = 1;
$myHash{'41893'} = 1;
$myHash{'41896'} = 1;
$myHash{'43400'} = 1;
$myHash{'44583'} = 1;

$myHash{'41889'}{'ROYAMT'} = 1.70;
$myHash{'41890'}{'ROYAMT'} = 1.70;
$myHash{'41893'}{'ROYAMT'} = 0.73;
$myHash{'41896'}{'ROYAMT'} = 2.00;
$myHash{'43400'}{'ROYAMT'} = 1.70;
$myHash{'44583'}{'ROYAMT'} = 0.39;

$myHash{'41889'}{'TITLE'} = "One";
$myHash{'41890'}{'TITLE'} = "Two";
$myHash{'41893'}{'TITLE'} = "Three";
$myHash{'41896'}{'TITLE'} = "Four";
$myHash{'43400'}{'TITLE'} = "Five";
$myHash{'44583'}{'TITLE'} = "Six";

print Data::Dumper->Dump([\%myHash]);
print "\n";
print Data::Dumper->Dump([\%{$myHash{'41889'}}]);
print Data::Dumper->Dump([\%{$myHash{'41890'}}]);
print Data::Dumper->Dump([\%{$myHash{'41893'}}]);
print Data::Dumper->Dump([\%{$myHash{'41896'}}]);
print Data::Dumper->Dump([\%{$myHash{'43400'}}]);
print Data::Dumper->Dump([\%{$myHash{'44583'}}]);
exit (0);

The output:
============================================================================
$VAR1 = {
          44583 => 1,
          41893 => 1,
          43400 => 1,
          41896 => 1,
          41890 => 1,
          41889 => 1
        };

$VAR1 = {
          'TITLE' => 'Six',
          'ROYAMT' => '0.39'
        };
$VAR1 = {
          'TITLE' => 'Six',
          'ROYAMT' => '0.39'
        };
$VAR1 = {
          'TITLE' => 'Six',
          'ROYAMT' => '0.39'
        };
$VAR1 = {
          'TITLE' => 'Six',
          'ROYAMT' => '0.39'
        };
$VAR1 = {
          'TITLE' => 'Six',
          'ROYAMT' => '0.39'
        };
$VAR1 = {
          'TITLE' => 'Six',
          'ROYAMT' => '0.39'
        };
============================================================================

I believe I understand why Data::Dumper can see both a scalar and a hash
stored at each of the locations since the hash values can store both a
scalar and a hash reference in the same node.  What I don't understand is
why the same hash reference is repeated for each what I would have expected
would have been different nodes with different hash reference slots--one per
primary hash key.

That is, I would have expected that $myHash{41889}{ROYAMT} would be a
distinct
hash node that would contain a scalar 1 and a hash reference that points to a
value of 1.70 while $myHash{44583}{ROYAMT} would be a distinct hash node that
contains a scalar 1 and a hash reference that points to a value of 0.39.

Does anyone have a picture they could draw to show me what is happening?

Thanks,
Paul

 -----  Posted via NewsOne.Net: Free (anonymous) Usenet News via the Web  -----
  http://www.*-*-*.com/ ,000+ groups
   NewsOne.Net prohibits users from posting spam.  If this or other posts



Tue, 14 Oct 2003 21:39:53 GMT  
 What causes this bizarre hash behavior?

Quote:
> $myHash{'41889'} = 1;
> $myHash{'41889'}{'ROYAMT'} = 1.70;

You are using the string "1" as a hash reference here, so "1.70" has
actually been stored in the hash %1, under $1{'41889'}.

If you put

        use strict 'refs';

at the top of your program, Perl will abort with a fatal error
message:

        Can't use string ("1") as a HASH ref while "strict refs" in use...

Quote:
> I believe I understand why Data::Dumper can see both a scalar and a hash
> stored at each of the locations since the hash values can store both a
> scalar and a hash reference in the same node.

No, that is not at all what is happening.  You cannot store "both a
scalar and hash reference in the same name"---a hash reference *is* a
scalar.  You can only store one thing per hash element.  

All the ROYAMTs and TITLEs are going into %1.  Each one overwrites the
previous ones, which is why when you dump out %1, all you see is item Six.

Hope this helps.



Tue, 14 Oct 2003 22:30:14 GMT  
 What causes this bizarre hash behavior?
Mark-Jason Dominus:

Thanks for the speedy reply!  Why isn't something about this
included in the hash section of the FAQ?  I searched a bunch
of places before posting to the group!

Thanks for the help!
Paul



Wed, 15 Oct 2003 03:56:28 GMT  
 What causes this bizarre hash behavior?
I was unaware youcould store a scalar and a hash reference in a hash - an I
am not sure you can.

If you run it use strict you will get the message:

Can't use string ("1") as a HASH ref while "strict refs" in
use at c:\a.pl line 14.

And obviously the following works:

#!/usr/local/bin/perl -w
#use strict;
use Data::Dumper;
my %myHash = ();
#$myHash{'41889'} = 1;
#$myHash{'44583'} = 2;
$myHash{'41889'}{number} = 1;
$myHash{'44583'}{number} = 2;

$myHash{'41889'}{'ROYAMT'} = 1.70;
$myHash{'44583'}{'ROYAMT'} = 0.39;

$myHash{'41889'}{'TITLE'} = "One";
$myHash{'44583'}{'TITLE'} = "Six";
print Data::Dumper->Dump([\%myHash]);
print "\n";
print Data::Dumper->Dump([\%{$myHash{'41889'}}]);
print Data::Dumper->Dump([\%{$myHash{'44583'}}]);



Mon, 20 Oct 2003 01:17:02 GMT  
 What causes this bizarre hash behavior?

Quote:

>Subject: What causes this bizarre hash behavior?

"autovivification"  (perldoc perlref)

(or the lack of autovivification)

Quote:
>If you run it use strict you will get the message:

>Can't use string ("1") as a HASH ref while "strict refs" in
>use at c:\a.pl line 14.

>And obviously the following works:

>#!/usr/local/bin/perl -w
>#use strict;
>use Data::Dumper;
>my %myHash = ();
>#$myHash{'41889'} = 1;
>#$myHash{'44583'} = 2;

Since you have the above commented out, $myHash{'41889'} has a value
of undef. When you use that undef value as if it was a reference below,
autovivification is triggered, and it creates the hash for you, and
then enters the key/value pair. All is well.

If you want to create a hash where there is _already_ a value,
you cannot get autoviv to do it for you, you must do it yourself:

   $myHash{'41889'} = {};   # overwrite whatever was there with a
   $myHash{'44583'} = {};   #    ref to an empty hash

Quote:
>$myHash{'41889'}{number} = 1;
>$myHash{'44583'}{number} = 2;

autoviv only happens when you use an undef value as if it was a
reference to a hash or array.

--
    Tad McClellan                          SGML consulting

    Fort Worth, Texas



Mon, 20 Oct 2003 04:03:32 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Number to Speech Function needed

2. bizarre(?) problem, tied hash of tied hashes

3. Bizarre mod_perl behavior

4. bizarre PERL/CGI behavior question

5. bizarre REQUIRE behavior

6. Truly bizarre do FILE behavior

7. bizarre $var->method behavior

8. Bizarre regexp behavior (bug?)

9. array of pointers

10. << NEED ODBC v3.0 - Please Help >>

11. Bizarre copy of HASH in debugger

12. Bizarre copy of HASH

 

 
Powered by phpBB® Forum Software