By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,852 Members | 1,410 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,852 IT Pros & Developers. It's quick & easy.

Array of references - what am I doing wrong?

P: 1
I am trying to create an array of references to arrays.

When I run the code below, it shows the correct data being pushed onto the array, but when I print it out at the end, every value is "3".

Any ideas?

Thanks,

Steve

Expand|Select|Wrap|Line Numbers
  1.      for ($i=0; $i < @key_columns; $i++) {
  2.         if ($i == 0) {
  3.             $where = " where $key_columns[$i] = ?";
  4.         } else {
  5.             $where .= " and $key_columns[$i] = ?";
  6.         }
  7.     }
  8.  
  9.     $sql_template = "select $key from $table $where";
  10.     $sth = $dbh->prepare($sql_template);
  11.     print "Prepared SQL is $sql_template\n";
  12.     $cnt = 0;
  13.     for $row (@$rows) {
  14.         $cnt++;
  15.         print "$cnt: @$row\r";
  16.         $got_row = 0;
  17.         print "Calling execute on @$row\n";
  18.         $sth->execute(@$row);
  19.         $primary_keys = $sth->fetchall_arrayref;
  20.         $rows_retrieved = int(@$primary_keys);
  21.         print "Got back $rows_retrieved\n";
  22.         $cnt += $rows_retrieved;
  23.         $got_row = 1 if @$primary_keys > 0;
  24.         for $primary_key (@$primary_keys) {
  25.             print "pushing @$primary_key\n";  # This data prints out correctly
  26.             push @new_keys, [ @$primary_key ];
  27. #            push @new_keys, $primary_key;  -  I also tried it like this, same result
  28.  
  29.         }
  30.  
  31. # If we can't match the key from the key table with a row in the original table (probably due
  32. # to corruption), push that key into the list of primary keys, anyway; we can try matching
  33. # against the backup tables later...
  34.  
  35.         if (! $got_row && $keys_same) {
  36.             push @new_keys, $row;
  37.         }
  38.     }
  39.     for $primary_key (@new_keys) { # This prints out wrong
  40.         print "key: " . @$primary_key . "   $primary_key  \n";
  41.     }
  42.  
Jan 15 '08 #1
Share this Question
Share on Google+
2 Replies


rickumali
P: 20
The code looks OK, but I suspect that there's probably one more dereference that needs to made. For issues like these, I typically break out the Perl Debugger, or drop in some Dumpvalue code.

For you, add this:

use Dumpvalue;
$dumper = new Dumpvalue;

Then right before the bad for loop, do this:

$dumper->dumpValue(\@new_keys);

You might have to play with this syntax, but basically dumpValue will generate an outline of the array, and from that you should be able to figure out how to dereference the thing. Good luck!
Jan 15 '08 #2

nithinpes
Expert 100+
P: 410
I am trying to create an array of references to arrays.

When I run the code below, it shows the correct data being pushed onto the array, but when I print it out at the end, every value is "3".

Any ideas?

Thanks,

Steve

Expand|Select|Wrap|Line Numbers
  1.      for ($i=0; $i < @key_columns; $i++) {
  2.         if ($i == 0) {
  3.             $where = " where $key_columns[$i] = ?";
  4.         } else {
  5.             $where .= " and $key_columns[$i] = ?";
  6.         }
  7.     }
  8.  
  9.     $sql_template = "select $key from $table $where";
  10.     $sth = $dbh->prepare($sql_template);
  11.     print "Prepared SQL is $sql_template\n";
  12.     $cnt = 0;
  13.     for $row (@$rows) {
  14.         $cnt++;
  15.         print "$cnt: @$row\r";
  16.         $got_row = 0;
  17.         print "Calling execute on @$row\n";
  18.         $sth->execute(@$row);
  19.         $primary_keys = $sth->fetchall_arrayref;
  20.         $rows_retrieved = int(@$primary_keys);
  21.         print "Got back $rows_retrieved\n";
  22.         $cnt += $rows_retrieved;
  23.         $got_row = 1 if @$primary_keys > 0;
  24.         for $primary_key (@$primary_keys) {
  25.             print "pushing @$primary_key\n";  # This data prints out correctly
  26.             push @new_keys, [ @$primary_key ];
  27. #            push @new_keys, $primary_key;  -  I also tried it like this, same result
  28.  
  29.         }
  30.  
  31. # If we can't match the key from the key table with a row in the original table (probably due
  32. # to corruption), push that key into the list of primary keys, anyway; we can try matching
  33. # against the backup tables later...
  34.  
  35.         if (! $got_row && $keys_same) {
  36.             push @new_keys, $row;
  37.         }
  38.     }
  39.     for $primary_key (@new_keys) { # This prints out wrong
  40.         print "key: " . @$primary_key . "   $primary_key  \n";
  41.     }
  42.  
Hi Steve,
The problem in your script is with usage of global variables. The print statement in line 25 prints out proper data because with each iteration of the loop the value of $primary_keys change and hence the array @$primary_keys.
But finally you end up with array(@new_keys) of anonymous arrays in which each array reference points to $primary_keys.Hence, array elements contain only the last row of data.

To overcome this, modify line 19 from
$primary_keys=$sth-> fetchall_arrayref;
to:
my $primary_keys=$sth-> fetchall_arrayref;

This should fix the problem. 'my' keyword is used for declaring local variables. As a result anonymous arrays will be created from scratch with each iteration avoiding overlaps.

Regards,
Nithin
Jan 22 '08 #3

Post your reply

Sign in to post your reply or Sign up for a free account.