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

Hi there Monks!

I need to edit some of the data coming back from my query here before printing the results.
I am doing something wrong here, is this the proper way to create a new array ref with the edited values?
How could I do this?

... my $sth = $dbh->prepare($sql)|| die $dbh->errstr; $sth->execute() or die "$!\n"; my $ary_ref = $sth->fetchall_arrayref(); my $new_array_ref; foreach my $val (@$ary_ref){ my ($one, $two, $three, $four, $five, $six, $seven, $eight, $nine, $te +n, $eleven) =@$val; #edit here $one=~s/2009/01112009/g; $five=~s/204/APROV/g; $six=~s/john/John/g; #Data edited ready for the array ref push @{$new_array_ref} ,$one, $two, $three, $four, $five, $six, $seven +, $eight, $nine, $ten, $eleven; } print Dumper ($new_array_ref);

I am getting an error like : "Can't use string (" SOMETHING ") as an array ref while " strict refs" in use"
Thanks a lot!

Replies are listed 'Best First'.
Re: Can't Use String as an Array Ref Help!
by ikegami (Patriarch) on Apr 23, 2009 at 18:09 UTC

    I am getting an error like : "Can't use string (" SOMETHING ") as an array ref while " strict refs" in use"

    Where? I don't see what would output that error in that code.

    I could see the error popping later if you treat @$new_array_ref as rows of fields instead of a flat array.

    missing | v push @{$new_array_ref}, [ $one, $two, $three, $four, $five, $six, $sev +en, $eight, $nine, $ten, $eleven ];

    Update:

    By the way, DBI calls don't set $!, and it's silly to duplicate RaiseError. Cleaner:

    my $sth = $dbh->prepare($sql, { RaiseError => 1 }); $sth->execute(); my @new; while (my $row = $sth->fetch()) { $row[0] =~ s/2009/01112009/g; $row[4] =~ s/204/APROV/g; $row[5] =~ s/john/John/g; # Can't just push $row. # Must make copy of $row # according to DBI docs. push @new, [ @$row ]; } print(Dumper(\@new));
      I am still getting stranger errors, I am combiing one array ref with another like this:
      for my $i (0..$#$new_array_ref) { push @{$new_array_ref->[$i]}, @{ ref($sec_new_array_ref->[$i]) eq +'ARRAY' ? $sec_new_array_ref->[$i] : [(' ') x 3] +}; } unshift @{ $all_data_first }, $ref_header;

        I have no idea what that is suppose to do.
Re: Can't Use String as an Array Ref Help!
by graff (Chancellor) on Apr 24, 2009 at 02:31 UTC
    I am getting an error like : "Can't use string (" SOMETHING ") as an array ref while " strict refs" in use" ...

    I am still getting stranger errors...

    Strange as it may seem, it actually takes less effort to copy/paste the actual error message (including line number) into your post, rather than paraphrasing or summarizing it.

    Also, once you've provided the full and exact error message, it's not so very hard to paste in the snippet of code that contains the line number mentioned in the error message (and enough context to indicate how variables in that line have been assigned values). Of course, it also helps to add a comment, pinpointing the line that caused the error.

    Try those two things -- show the exact error message, and show the corresponding line of code with background code that shows how variables in that line were set -- and we'll probably be able to give better advice.

      OK I'll explain here with code what I am trying to accomplish, please let me know if you understand, I have comments on the code explaining as well, I would really appreciate any feed back on this!

      # Start first sql... my $dbh = DBI->connect... my $sql = " SELECT acc_num, date, user1, user2, email, user4, user5, user6, country, FROM users_info WHERE date='2009-04-11' "; my $sth = $dbh->prepare($sql, { RaiseError => 1 }); $sth->execute() or die "$!\n"; my $array_ref = $sth->fetchall_arrayref(); my (@ar_acc_num, $new_array_ref); foreach my $vals (@$array_ref){ my ($acc_num, $date, $user1,$user2,$email,$user4,$user5,$user6,$countr +y) =@$vals; #Now edit data here before saving it::: $data=~s/2000/2009/g; $user=~s/joe/Joe/g; #get edited data to the new array_ref::: Is this possible, is it how +it is done? push @{$new_array_ref}, $date, $user1,$user2,$user3,$user4,$user5,$use +r6,$user7; push @ar_acc_num ,$acc_num; # I will need to push $date into an array as well, but one problem at +a time. } # here I have part of the data I need, print for test print Dumper ($new_array_ref); #@ar_acc_num -> here I have all the acc numbers I need to go after on +the second table::: # Start second sql... my $dbh_b = DBI->connect... my $values = join("," ,map { $dbh_sec->quote($_) } @ar_acc_num ); my $sql_b = " SELECT add, acc, date, user3, phone, city, state, user7, reg FROM all_info WHERE date='2009' /* # it should be the value of $date pu +shed previously but for now I am using static year value of 2009 */ AND acc IN ($values) "; my $sth_b = $dbh_b->prepare($sql_b, { RaiseError => 1 }); $sth_b->execute() or die "$!\n"; my $array_ref_b = $sth_b->fetchall_arrayref(); my $new_array_ref_b; foreach my $vals_b (@$array_ref_b){ my ($add, $acc, $date,$user3,$phone,$city,$state,$user7,$reg) =@$vals_ +b; #Now edit data here before saving it::: $city=~s/new york/New York/g; $reg=~s/usa/USA/g; #get edited data to the new array_ref::: Is this possible, or how can + this be done? push @{$new_array_ref_b}, $add, $acc, $date,$user3,$phone,$city,$state +,$user7,$reg; } # print for test print Dumper ($new_array_ref_b); my $header = [ "Acc. Num", "Date", "User 1", "User 2", "User 3", "User 4", "User 5", "User 6", "User 7", "Add", "Acc", "Email", "Phone", "City", "State", "Country", "Regular", ]; # Here is another question and problem I am having, as you can see I n +eed to rearrange the columns to mach the order on $header, and # $email, $country are coming from the first query and $user3 and $use +r7 fro mthe second, I need to reorganize the data to have some consis +tency # when processing the rest of the code to be printed on this report. H +ow can this be done? # Here I need to add @{ $new_array_ref } to @{ $new_array_ref_b } to +contain all the data I need to print a report and # make sure that if data from the first table query has more data than + the results from the second table dont generate any error, if it is +it will # insert a '' to the value and it will print nice on the report for my $i (0..$#$new_array_ref) { push @{$new_array_ref->[$i]}, @{ ref($new_array_ref_b->[$i]) eq 'A +RRAY' ? $new_array_ref_b->[$i] : [(' ') x 3] }; } # This will add some data for the table header when printing this repo +rt that will be done in pdf later unshift @{ $new_array_ref }, $header; ##Now if all its done OK go here: main_table($pdf, \@{$new_array_ref}); $pdf->saveas(); sub main_table { my $pdf = shift; my $data = shift; do more stuff...... }


      Thanks!
        Your first problem would have been made clear if you included use strict; -- it's this line:
        $data=~s/2000/2009/g;
        That's the first mention of a variable named "$data" -- previously, you assigned a value from the DB to a variable called "$date". Apart from that, I can't see how $date =~ s/2000/2009/g would have any effect, unless your database server is seriously broken: your query specifically asks for rows where the date contains "2009", not "2000", so that s/// statement is a no-op.

        A couple lines later, there's a "$user7" variable being assigned to your $new_array_ref, but that was never mentioned previously either.

        Also, after making the connection for "$dbh_b", your "map" block uses something called "$dbh_sec" as if it were some kind of object, but that's the only mention of $dbh_sec. Bottom line: the code you posted will not run.

        As for pushing rows of field data into an AoA ref, I'll just repeat what was already mentioned in an earlier reply -- you do it like this (note the use of square brackets):

        my $new_array_ref; foreach my $vals (@$array_ref) # I'd use "$row" instead of "$vals", +but whatever { my ($acc_num,$date,$user1,$user2,$email,$user4,$user5,$user6,$coun +try) = @$vals; # do some edits that make sense... and then: push @$new_array_ref, [$date, $user1, $user2, ... ]; }

        There's no need (no use) for me to go any further. You actually didn't follow my earlier suggestion, and until you do start to follow suggestions, there's not much point trying to help you. So to repeat:

        USE STRICT. The things you need to do in order to make the script compile with use strict will probably fix your problems.

        Come up with a version of the code that includes "use strict" and actually compiles, runs and produces some specific result (whether an error message or some sort of data output).

        If the result is the intended data, you're done (yay!). If not, and if you really can't figure out the problem on your own, show us the specific result that is relevant to the problem (exact error message, Data::Dumper output or whatever -- but keep it brief and relevant).

        If there's an error with a line number show us the specific line of code in question, with just the relevant background code to show how the variables in the error line were set up. (Posting a long stream of code that does not compile will not help you here, and will only annoy people.)