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

Problem with code: when assigning a value to a associative array ex.
$TT{1100}[1][1]= "gg";
the next associative array with $TT{'1101'}[1][1] also gets
the value please explained & help? <br
I understand that with associative array that when you access the values on the array only the values that are associated with a particular key are changed, but may problem is some how may code is assigning values to different key's. i dont know if its on perl or code error?

Has been tested using ActivePerl 5.6.1 &
on unix: Apachi perl -v version 5.005_03 built for i386-freebsd
#!/usr/bin/perl print "Content-type: text/html\n\n"; #Program # Values From Web Page using Post to Simulate Values $INPUT{'quizes'}=2; $INPUT{'assign'}=2; $INPUT{'recit'}=2; $INPUT{'ndays'}=1; $INPUT{'AT32000011'}=1; $INPUT{'QZ132000011'}=1; $INPUT{'RI132000011'}=1; $INPUT{'AS132000011'}=1; $INPUT{'QZ232000011'}=2; $INPUT{'RI232000011'}=2; $INPUT{'AS232000011'}=2; $INPUT{'AT32000012'}=1; $INPUT{'QZ132000012'}=12; $INPUT{'RI132000012'}=12; $INPUT{'AS132000012'}=12; $INPUT{'QZ232000012'}=22; $INPUT{'RI232000012'}=22; $INPUT{'AS232000012'}=22; #Values From File to Simulate with out the files $STUDQT{'32000011'}[0] = 'fname'; $STUDQT{'32000011'}[1] = 'mname'; $STUDQT{'32000011'}[2] = 'lname'; $STUDQT{'32000011'}[3] = 'Sex'; $STUDQT{'32000011'}[1]['01'] = '0'; $STUDQT{'32000011'}[1]['02'] = '0'; + + ; $STUDQT{'32000011'}[1]['03'] = '0'; $STUDQT{'32000011'}[1]['04'] = '0'; $STUDQT{'32000012'}[0] = 'fname'; $STUDQT{'32000012'}[1] = 'mname'; $STUDQT{'32000012'}[2] = 'lname'; $STUDQT{'32000012'}[3] = 'Sex'; $STUDQT{'32000012'}[1]['01'] = '0'; $STUDQT{'32000012'}[1]['02'] = '0'; + + ; $STUDQT{'32000012'}[1]['03'] = '0'; $STUDQT{'32000012'}[1]['04'] = '0'; #-------------------------------------------- @sorted = sort { "$STUDQT{$a}[3] $STUDQT{$a}[2] $STUDQT{$a}[0]" cmp "$ +STUDQT{$b}[3] $STUDQT{$b}[2] $STUDQT{$b}[0]" } keys %STUDQT; #-----------------------------------Get The Inputs From User foreach $l (@sorted) { #--------------------------------------------------------------------- +------------------- $STUD_1 = ""; $STUD_1 = "$STUDQT{$l}[1]['02']"; for ($i = 1; $i < $INPUT{'assign'}+1; $i+=1) { if ($INPUT{"AS$i$l"}) { $STUD_1 = "$STUD_1$INPUT{\"AS$i$l\"}"; if (($INPUT{'assign'}) != $i) { $STUD_1 .= "~";} } } $STUDQT{"$l"}[1]['02'] = "$STUD_1"."^"; #Problem print "Values for fist key in an associative array with key('3 +2000011')is = $STUDQT{'32000011'}[1]['02'] <br>\n"; print "Problem is a Value has also some how been assigned to t +he next key in an associative array<br>\n"; print "Values for next array with key{'32000012'} is = $STUDQT +{'32000012'}[1]['02'] <br>\n"; print "--------------------------------<br><br>\n\n"; }

Edit Masem 2001-11-02 - Added CODE tags at start

Replies are listed 'Best First'.
Re (tilly) 1: associative array problem
by tilly (Archbishop) on Nov 02, 2001 at 20:17 UTC
    As noted in chatter, you should be using CGI, and your code could use some refactoring.

    However the source of the problem would be caught by strict.pm. The problem is that you are assigning into slot 1 the string 'mname', and then you are proceeding to access it as if it was an array. (Note, you are using brackets, and not braces.) Perl tries to figure out what you mean by that, and guesses that you want to access the global array @mname. So you overwrite the same array each time and wind up with grief.

    My immediate suggestion is that you use strict.pm and study references quick reference. And then be sure to use CGI.

      To clarify that a bit, the program can be reduced to:

      my %STUDQT; $STUDQT{11} = [qw/fname mname/]; $STUDQT{11}[1][2] = 0; #$STUDQT{12} = [qw/fname mname/]; $STUDQT{12}[1][2] = 0; print qq|\$STUDQT{11}[1][2] = $STUDQT{11}[1][2]\n|, qq|\t\$STUDQT{12}[1][2] = $STUDQT{12}[1][2]\n|; $STUDQT{11}[1][2] = 'hello'; #Problem print qq|\$STUDQT{11}[1][2] = $STUDQT{11}[1][2]\n|, qq|\t\$STUDQT{12}[1][2] = $STUDQT{12}[1][2]\n|; __END__
      Don't use strict and run it as is:
      $STUDQT{11}[1][2] = 0 $STUDQT{12}[1][2] = 0 $STUDQT{11}[1][2] = hello $STUDQT{12}[1][2] = 0
      Just as we expect. But uncomment: #$STUDQT{12} =  [qw/fname mname/]; and we get:
      $STUDQT{11}[1][2] = 0 $STUDQT{12}[1][2] = 0 $STUDQT{11}[1][2] = hello $STUDQT{12}[1][2] = hello

      Turning on strict reveals that we are attempting to use 'mname' as a symbolic reference and perl guesses what we are attempting as tilly mentioned.

      HTH,
      Charles K. Clarkson

      It is an array a multidimensional array at that, the script is from a much more complex script it is just a simulation of the problem. So instead of getting the values from STDIN ex.

      read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($names, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($INPUT{$names}) { $INPUT{$names} = $INPUT{$names}.",".$val +ue; } else { $INPUT{$names} = $value; } }
      I have assigned it directly to array! & Instead of including the file and accessing it and load it in an array using loops I just directly given its values for the sake of the simulation.

      I don?t understand what you mean my CGI? But if its on the extension its the same!
        You are parsing your CGI input directly, and doing it in a broken way. What I was talking about is using the standard CGI module to parse your input for you, more flexibly, meeting the whole standard, without security holes, with support for file uploads, with support for command line debugging, etc, etc, etc. Read use CGI or die; for details on what people typically get wrong (yes, you made the typical mistakes), and for simple examples of how to use the module.

        As for the problem you complained about, I already told you why you have the behaviour you do, and how to automatically catch the error that leads to it. And what I meant by saying that you're using an array instead of a hash is that you are using strings like '01' as indexes into an array. I strongly recommend either making that a hash, or just using numbers. As it stands your choice of index and data structure are passing conflicting messages. Experienced programmers see conflicts like that and label them as mistakes. What kind of mistake may not be obvious, but they are mistakes.

        UPDATE
        BTW you may find it better to just use a nested hash. For instance if you just assign your values like:

        $STUDQT{'32000012'}{mname}[1] = 0;
        without initializing $STUDQT{'32000012'}{mname}, Perl will no longer misbehave on you. (Of course strict.pm is still strongly recommended to catch other incidences of the same mistake. Catching bugs early is a Good Thing.)
(jeffa) Re: associative array problem
by jeffa (Bishop) on Nov 02, 2001 at 20:28 UTC
    Big advice when asking a question: explain what you are trying to do!!!

    The reason why is because if we solve your problem, we are just treating the symtom - not the real problem. I have a good feeling you are doing far too much work . . .

    The only other advice i can give is style pointers on your code. First off the INPUT hash could be initiated like so:

    my %INPUT = ( quizes => 2, assign => 2, recit => 2, ndays => 1, AT32000011 => 1, QZ132000011 => 1, RI132000011 => 1, AS132000011 => 1, QZ232000011 => 2, RI232000011 => 2, AS232000011 => 2, AT32000012 => 1, QZ132000012 => 12, RI132000012 => 12, AS132000012 => 12, QZ232000012 => 22, RI232000012 => 22, AS232000012 => 22, );
    And you can populate your first two keys in the STUDQT hash like so:
    foreach (32000011..32000012) { push @{$STUDQT{$_}}, qw(fname mname lname Sex); }
    But, $STUDQT{'32000011'}[1]['01'] =  '0'; is just wrong, wrong, wrong! What are you trying to do here? Well, you are obviously trying to initalize that value, but why do you need hash of lists of hashes? My first impression is that you meant to say $STUDQT{'32000011'}[1]{'01'} = 0;, but that doesn't make sense either. . .

    Please use Data::Dumper when dealing with complex data structures like %STUDQT, here is what it looks like after the last initialization line:

    use Data::Dumper; print Dumper \%STUDQT; #yields: $VAR1 = { '32000011' => [ 'fname', 'mname', 'lname', 'Sex' ], '32000012' => [ 'fname', 'mname', 'lname', 'Sex' ] };
    as you can see, '01', '02', etc are not there, meaning that those 8 lines of code that 'define' them are uneccesary.

    jeffa

    A reply falls below the community's threshold of quality. You may see it by logging in.