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

UPDATENo need to reply to this one have found my mistake in the original code and rectified. Sorry to anyone who has spent time looking at this. I probably owe you all a trapist beer from The Abbey Leffe.

Thanks for all your help with my last dereferencing problem and sorry that my code was not very clear, I was working that day with a Leffe (Belgium Beer) hang over, I wasn't to sharpe. I belived that I had hashes and references clear until today when I tried the following.
I am working on testing some perl scripts, translated by someone else, which replace SCL main frame code on a new server. The scripts replicate the convention of a variable having a name, localname and default value. I have also xml files with data about the scripts from which I can extract the data I need to run my testing programs. I have come up with the following code.

sub make_var_hash{ my $xml = @_[0]; my %myhash; my $name; my $localname; my $defaultval; # #read the xml file extract the data and add to the following hash #UPDATE sorry this line should be $myhash{$name} = [$localname,$defaultval]; #NOT $myhash{$name} = ($localname,$defaultval); #end the loop return \%myhash; }
In my calling script
$hash1 = make_var_hash('MOR2305.xml'); foreach $key (keys($hash1)){ print "$key = $$hash1{$key}[0] & $$hash1{$key}[1]\n"; }
Works fine with the following result
START = MOR_START & 60 FINISH = MOR_FINISH & 150 etc....
Just what I needed!
However many of the scripts are strung together in suites and it would be useful to me to create a hash referencing the hashes created in in make_vars_hash.
So I tried this
sub get_suite_vars{ my %suite; my ($job_vars, $job); my @jobs = ('MOR2305.xml', 'MOP4312.xml', 'IN543.xml'); foreach $job ($job_vars){ $job_vars = make_var_hash($job); $suite{$job} = $job_vars; } return \$suite; }
However back in my calling script I started to get some starnge results and to stop a long story getting longer I changed above to.
sub get_suite_vars{ my %suite; my ($job_vars, $job); my @jobs = ('MOR2305.xml', 'MOP4312.xml', 'IN543.xml'); foreach $job ($jobs){ $job_vars = make_var_hash($job); #UPDATE for anyone interested the error was here #In my original code I had foreach $key($job_vars){ #SORRY foreach $key (keys($job_vars)){ print "$key = $$job_vars{$key}[0] & $$job_vars{$key}[1]\n"; } $suite{$job}=$job_vars; } return \$suite; }
Which produced
START = MOR_START & ARRAY(0x1930fo30) = & FINISH = MOR_FINISH & ARRAY(0x1931eaf0) = & etc....
Not what the doctor ordered. Whats happening? The code has been shortened a little but in principle is the same. Any help greatfully excepted.
Slight up date to inc. the file name in the first call to make_var_hash

Replies are listed 'Best First'.
Re: More dereferencing
by geekgrrl (Pilgrim) on May 04, 2004 at 16:02 UTC
    In get_suite_vars, you need to change
    foreach $key (keys($job_vars)){
    to
    foreach $key (keys (%{$job_vars} ) ) {
    Also I would change
    print "$key = $$job_vars{$key}[0] & $$job_vars{$key}[1]\n";
    to
    print "$key = $job_vars->{$key}[0] & $job_vars->{$key}[1]\n";
    Plus, just to be sure that the data strcutures look ok, I would add a line like (use Data::Dumper at top of code)
    print Dumper $job_vars;
    oh yeah - using strict will help a lot too...
      Thank you for your help. Have never got to grips with Dumper looks like now would be a good time. Thanks for all your help!
Re: More dereferencing
by dave_the_m (Monsignor) on May 04, 2004 at 16:04 UTC
    Well, the code you show can't possibly work, because you have keys($foo) in a couple of places when it should be keys(%$foo)

    Probably your best bet would be to reduce your code to a simple test case that still shows the problem, then post the whole code here if it still fails. The very process of reducing the code often turns up where the problem is.

    And my a simple case, I mean simple; ie remove all the XML and file reading stuff, and replace the heart of make_var_hash with something like

    if ($xml eq 'file1') { $myhash{foo1} = ['bar1', 55 ]; $myhash{foo2} = ['bar2', 55 ]; } elsif ($xml eq '...
      Thanks for your interest I have done the very thing you suggested and have now seen the wood for the trees!
      Thanks again!