in reply to Re: Why is my code assigning the last-retrieved value to all elements in my hash?
in thread Why is my code assigning the last-retrieved value to all elements in my hash?

Hmmm...several fingers pointed at referencing the hash so far in this thread...

The %booklist_1 hash is populated from a previous query, like this:

$sql = "SELECT book_id FROM booklist_table WHERE (expected_publcn_date + >= '".$start_date."' AND expected_publcn_date <= '".$end_date."')"; $sth = $dbh->prepare($sql) or die("Could not prepare!" . $dbh->errstr) +; $sth->execute() or die("Could not execute!" . $dbh->errstr); while ($book_id = $sth->fetchrow_array()) { $booklist_1{$book_id} = 1; } $sth->finish;



Time flies like an arrow. Fruit flies like a banana.
  • Comment on Re^2: Why is my code assigning the last-retrieved value to all elements in my hash?
  • Download Code

Replies are listed 'Best First'.
Re^3: Why is my code assigning the last-retrieved value to all elements in my hash?
by kyle (Abbot) on Jul 09, 2008 at 18:53 UTC

    Use strict and warnings!!!

    use Data::Dumper; my %booklist_l; $booklist_l{ 'foo' } = 1; $booklist_l{ 'bar' } = 1; $booklist_l{ 'foo' }{ 'update_id' } = 'update_id 1'; $booklist_l{ 'foo' }{ 'title' } = 'title 1'; $booklist_l{ 'bar' }{ 'update_id' } = 'update_id 2'; $booklist_l{ 'bar' }{ 'title' } = 'title 2'; print Dumper \%booklist_l; print Dumper \%1; __END__ $VAR1 = { 'bar' => 1, 'foo' => 1 }; $VAR1 = { 'update_id' => 'update_id 2', 'title' => 'title 2' };

    That number '1' you put into every entry is being treated as a symbolic reference to the variable %1.

      Excellent.

      So, since the '1' just serves to give a value that allows the element to exist, setting to something, anything, else should serve teh same purpose and avoid the undesired symbolic reference to %1.

      Went ahead and changed it to

      while ($book_id = $sth->fetchrow_array()) { $booklist_1{$book_id} = "ok"; }
      but it made no difference. Same output.

      I really appreciate the attention to my prob, though. Did I miss-apply what you were trying to say?




      Time flies like an arrow. Fruit flies like a banana.

        Did I miss-apply what you were trying to say?

        Yes.

        Change "ok" to {}, and that should work.

        while ($book_id = $sth->fetchrow_array()) { $booklist_1{$book_id} = {}; }

        Even then, I urge you to Use strict and warnings. It would have saved you from creating this problem in the first place. Instead of silently doing what you didn't want, it would have told you on its death bed,

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

        It's not the best error message in this case, but it would have served better than the mystery you had. If you'd not been able to figure it out, you could have posted it here, and we would have been able to answer immediately rather than groping around.

        So I say a third time, Use strict and warnings

Re^3: Why is my code assigning the last-retrieved value to all elements in my hash?
by karavelov (Monk) on Jul 09, 2008 at 19:40 UTC
    I think the bug is here. Try to write something like
    while ( ($book_id) = $sth->fetchrow_array() ) { $booklist_1{$book_id} = 1; }
    (note the extra parenthesis in order to enforce list context)

    or

    while ( $book_id = $sth->fetchrow_arrayref() ) { $booklist_1{ $book_id->[0] } = 1; }

    Code is not tested

    Best regards

    UPDATE:. I have overseen the kyle suggestion. It seems that the right code regarding the second loop will be:

    while ( ($book_id) = $sth->fetchrow_array() ) { $booklist_1{$book_id} = {}; }