Tanton,

I've been working on a complete example of this problem. I think that I can
demonstrate a couple of oddities with the code that follows. The first set
of code works on Perl 5.005_3 and demonstrates that exists works correctly
and that both methods of referencing (and setting) structures in hashes does
work. The second set of code is basically the same. Except that I do not
use, in any way, the "AnyID" field in the structure. For some reason, on
Perl 5.6.1, this code will work as expected with respect to the exists
function. Which means that you can get into the loop where data is being
added to the hash.

But, attempts to reference a field in the structure results in different
values depending on the method used under 5.6.1. Under older versions, this
seems to work fine.

1. Put a break in the BuildHash function prior to the for loop. The first
time that this loop is executed the exists function should be false because
nothing has been added to the hash. On Perl 5.005_03 this works as expected.
The exists function returns true only after a hash with a duplicate key has
been added. On Perl 5.6.1, the exists function returns true even the very
first time that the function is called.

Ron


This set of code works on Perl 5.005_3 and demonstrates a hash of structures
where the values can be read and set. Also the exists function does work.

--------------
use strict;

use Class::Struct;                      #To enable structures
use Date::Manip;

$main::TZ = "US/Central";

#############################
# C O N S T A N T S
#############################
my $TRUE = 1;
my $FALSE = 0;

#############################
# G L O B A L s
#############################
my ($curr_key, @index, $nSecond, $nFixed);
my (%MyHash);

#############################
# S T R U C T U R E S
#############################
#This structure will be stored in the MyHash. The key for the MyHash will be
the CTBT
#as determined by lookup against the CTBT_ProductMappings table.
struct TestStruct => {       # The data structure
        AnyID                                           => '$',                 #ID
        CurrentDateTime => '$',                 #The current date and time
};

#############################
# S U B R O U T I N E S
#############################
sub BuildHash
{
        my ($lclCurrentDateTime);
        my ($lclKey, $p, $n, $nCurrentSecond);

        for ($n=0; $n<25; $n++)
        {
                $lclCurrentDateTime = DateCalc("today");

                $nCurrentSecond = int(UnixDate($lclCurrentDateTime, "%S"));
                $nCurrentSecond = sprintf("%02s", $nCurrentSecond);

                $lclKey = $nCurrentSecond.sprintf("%03s", $n % 3);

                #Check to see if this key is already present in the hash
                #if the key is found, then change the current time value
                if (exists($MyHash{$lclKey}) == 1)
                {
                        print "Hash entry already existed. ID was 
".$MyHash{$lclKey}{AnyID}." Old
time was ".$MyHash{$lclKey}{CurrentDateTime}."\n";                      #51
                        print "Hash entry already existed. ID was 
".$MyHash{$lclKey}->AnyID." Old
time was ".$MyHash{$lclKey}->CurrentDateTime."\n";                      #52

                        $MyHash{$lclKey}{CurrentDateTime} = "100";      #Setting the 
new value this
way does NOT work
                        $MyHash{$lclKey}{AnyID}++;
                        #$MyHash{$lclKey}->CurrentDateTime = $lclCurrentDateTime;      
 #This won't
work because of the -> operator
                        #$MyHash{$lclKey}->CurrentDateTime("100");
                        #$MyHash{$lclKey}->AnyID($MyHash{$lclKey}->AnyID + 1);

                        print "Hash entry already existed. ID is 
".$MyHash{$lclKey}{AnyID}." New
time is ".$MyHash{$lclKey}{CurrentDateTime}."\n";
                        print "Hash entry already existed. ID is 
".$MyHash{$lclKey}->AnyID." New
time is ".$MyHash{$lclKey}->CurrentDateTime."\n";
                }
                else    #Creating a new hash entry
                {
                        $p = TestStruct->new();                         #allocate a 
new structure to hold the
information

                        $p->CurrentDateTime($lclCurrentDateTime);       #Store the 
full date and time
                        $p->AnyID($n);  #Store the loop counter when this struct was 
first created

                        $MyHash{$lclKey} = $p;          #Add this structure to the hash
                }
        }
}


################################
######## Main Program ##########
################################

######  init globals  ################
BuildHash();

#Display hash
        #Loop through the hash data and update the database accordingly
        @index = sort (keys (%MyHash));

        foreach $curr_key (@index)
        {
                #Dissect the key
                $nSecond = substr($curr_key, 0, 2);
                $nFixed = substr($curr_key, 2, 3);

                print "The data date stored in the hash is Second: $nSecond, Fixed Key:
$nFixed, for current date and time of:
".$MyHash{$curr_key}->CurrentDateTime."\n";
        }
-----------------------


Here's the second set of code that does not use the AnyID field.
-----------------------
use strict;

use Class::Struct;                      #To enable structures
use Date::Manip;

$main::TZ = "US/Central";

#############################
# C O N S T A N T S
#############################
my $TRUE = 1;
my $FALSE = 0;

#############################
# G L O B A L s
#############################
my ($curr_key, @index, $nSecond, $nFixed);
my (%MyHash);

#############################
# S T R U C T U R E S
#############################
#This structure will be stored in the MyHash. The key for the MyHash will be
the CTBT
#as determined by lookup against the CTBT_ProductMappings table.
struct TestStruct => {       # The data structure
        AnyID                                           => '$',                 #ID
        CurrentDateTime => '$',                 #The current date and time
};

#############################
# S U B R O U T I N E S
#############################
sub BuildHash
{
        my ($lclCurrentDateTime);
        my ($lclKey, $p, $n, $nCurrentSecond);

        for ($n=0; $n<25; $n++)
        {
                $lclCurrentDateTime = DateCalc("today");

                $nCurrentSecond = int(UnixDate($lclCurrentDateTime, "%S"));
                $nCurrentSecond = sprintf("%02s", $nCurrentSecond);

                $lclKey = $nCurrentSecond.sprintf("%03s", $n % 3);

                #Check to see if this key is already present in the hash
                #if the key is found, then change the current time value
                if (exists($MyHash{$lclKey}) == 1)
                {
                        print "Hash entry already existed. Old time was
".$MyHash{$lclKey}{CurrentDateTime}."\n";
                        print "Hash entry already existed. Old time was
".$MyHash{$lclKey}->CurrentDateTime."\n";

                        $MyHash{$lclKey}{CurrentDateTime} = "100";      #Setting the 
new value this
way does NOT work
                        #$MyHash{$lclKey}{AnyID}++;
                        #$MyHash{$lclKey}->CurrentDateTime = $lclCurrentDateTime;      
 #This won't
work because of the -> operator
                        #$MyHash{$lclKey}->CurrentDateTime("100");
                        #$MyHash{$lclKey}->AnyID($MyHash{$lclKey}->AnyID + 1);

                        print "Hash entry already existed. New time is
".$MyHash{$lclKey}{CurrentDateTime}."\n";
                        print "Hash entry already existed. New time is
".$MyHash{$lclKey}->CurrentDateTime."\n";
                }
                else    #Creating a new hash entry
                {
                        $p = TestStruct->new();                         #allocate a 
new structure to hold the
information

                        $p->CurrentDateTime($lclCurrentDateTime);       #Store the 
full date and time
                        #$p->AnyID($n); #Store the loop counter when this struct was 
first
created

                        $MyHash{$lclKey} = $p;          #Add this structure to the hash
                }
        }
}


################################
######## Main Program ##########
################################

######  init globals  ################
BuildHash();

#Display hash
        #Loop through the hash data and update the database accordingly
        @index = sort (keys (%MyHash));

        foreach $curr_key (@index)
        {
                #Dissect the key
                $nSecond = substr($curr_key, 0, 2);
                $nFixed = substr($curr_key, 2, 3);

                print "The data date stored in the hash is Second: $nSecond, Fixed Key:
$nFixed, for current date and time of:
".$MyHash{$curr_key}->CurrentDateTime."\n";
        }

------------------------

-----Original Message-----
From: Gibbs Tanton - tgibbs [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, August 22, 2001 1:33 PM
To: 'Ron Rohrssen '; Gibbs Tanton - tgibbs; ''Perl Beginners ' '
Subject: RE: Hash of structures not working in latest Perl build on
Window s?


As far as the behavior of exists...I don't have your full source so I don't
know.  I would recommend going back and making sure you NEVER touch
$AccumHash{whatever}.  Look for defines (instead of exists), method calls
(such as $AccumHash{whatever}->DataDate()) or anything that might autovivify
$AccumHash{whatever}. Furthermore, keys(%AccumHash) = 0 doesn't do what I
think you want to do.  To empty a hash, try %AccumHash = ();

Also, you should be able to update the DataDate member by saying
$ref->DataDate('MyDate');



-----Original Message-----
From: Ron Rohrssen
To: Gibbs Tanton - tgibbs; 'Perl Beginners '
Sent: 8/22/2001 10:48 AM
Subject: RE: Hash of structures not working in latest Perl build on Window
s?

THANKS!

That did work. Well, sort of....

Now there are errors in this:
if (exists($AccumHash{$lclKey}) == 1)
{
        #add data to existing structure in the hash
}
else
{
        #create new struct and add to hash
}

The very first time that I hit this code (the hash is empty), the exists
function returns a 1 and steps into the code for an existing structure
in
the hash. There's no way that the hash contains anything.

I've even tried this to insure that the hash is empty prior to hitting
the
above code for the first time.
keys(%AccumHash) = 0;

This leads to problems in other areas of the code as additional
references
to the hash cause unblessed references.

Another interesting effect is that I still have to update values in the
structure the "old" way. So, this only seems to effect reading the data
from
the structure.


Ron

-----Original Message-----
From: Gibbs Tanton - tgibbs [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, August 21, 2001 5:53 PM
To: '[EMAIL PROTECTED]'; 'Perl Beginners '
Subject: RE: Hash of structures not working in latest Perl build on
Window s?


Ok...I ran this on Unix with a simplified version and got the same
results
as you.

I'm not too familiar with Class::Struct, but if you specify your print
as
$AccumHash{$curr_key}->DataDate()
instead of
$AccumHash{$curr_key}{DataDate} it should work.  I'm not sure why the
underlying implementation changed, but
apparently it did...I would recommend changing to use the function
interface.

Good Luck!
Tanton

-----Original Message-----
From: Ron Rohrssen [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, August 21, 2001 5:17 PM
To: Gibbs Tanton - tgibbs; 'Perl Beginners '
Subject: RE: Hash of structures not working in latest Perl build on
Window s?


There aren't any error messages.

On the older Perl versions it will print out data stored in the
structure.
(i.e. DataDate in the example code). On the newer version 5.6.1, every
data
field in the structure is "" (empty string). Although, I can loop
through
the hash and correctly retrieve the keys.

I just can't get data stored in the structure.

Ron

-----Original Message-----
From: Gibbs Tanton - tgibbs [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, August 21, 2001 5:03 PM
To: 'Ron Rohrssen '; 'Perl Beginners '
Subject: RE: Hash of structures not working in latest Perl build on
Window s?


What does it not do...what did it used to do...are there any error
messages
or warnings now?

-----Original Message-----
From: Ron Rohrssen
To: Perl Beginners
Sent: 8/21/2001 3:49 PM
Subject: Hash of structures not working in latest Perl build on Windows?

I have a section of code the works on Win 98 and NT using Perl version
5.005_03.

However, the same code does not work under Win NT using Perl version
5.6.1.

Can someone help me identify why this does not work in the latest Perl
version?

Here is a code snippet.
-----------
#Create the hash with code like this
struct ReportStruct => {       # The data to store for accumulated data
 CallsTDD    => '$',   #A count of the number of calls meeting the TDD
criteria
 CallsVoice   => '$',   #A count of the number of calls meeting the
voice
criteria
 DataDate    => '$',   #The actual date when the BDR was cut, does not
include time
};


if (exists($AccumHash{$lclKey}) == 1)
 {
  $AccumHash{$lclKey}{CallsVoice} = $AccumHash{$lclKey}{CallsVoice} +
int($CallsVoice);
  $AccumHash{$lclKey}{CallsTDD} = $AccumHash{$lclKey}{CallsTDD} +
int($CallsTDD);
 }
 else #Creating a new hash element and add this to the list
 {
  $p = ReportStruct->new();    #allocate a new structure to hold the
information

  $p->CallsVoice(int($CallsVoice));
  $p->CallsTDD(int($CallsTDD));
  $p->DataDate($DataDate);

  $AccumHash{$lclKey} = $p;
 }

----------------
#Loop through the hash and work on the data in the hash
@index = sort (keys (%AccumHash));

 foreach $curr_key (@index)
 {
   print "The data date stored in the hash is
".$AccumHash{$curr_key}{DataDate}." for BDR File ".$BDR_FileName."\n";
 }

Thanks

Ron Rohrssen MCI

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to