Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

can't use string as an array ref....

by inblosam (Monk)
on Jul 13, 2005 at 00:11 UTC ( [id://474421]=perlquestion: print w/replies, xml ) Need Help??

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

In this node I got some advice on how to post and retrieve multiple rows of data. I am now getting an error using this: "Can't use string ("1") as an ARRAY ref while "strict refs" in use at...". I am using Mason, and one of the comments in the aforementioned node was trying to eliminate this problem, but I still get the same error (pointing to the "init" line).

The form being posted looks like this:
<input type="hidden" name="edit_item" value="1"> <input type="text" name="edit_name_1" value="hello" size="20">
The code that processes this looks as follows...
my @editlineitems = @{ $ARGS{ edit_item } }; foreach my $line (@editlineitems) { my $name = $ARGS{"edit_name_$line"}; }
Any help would be appreciated!


Michael Jensen

Replies are listed 'Best First'.
Re: can't use string as an array ref....
by monarch (Priest) on Jul 13, 2005 at 00:30 UTC
    It is possible, even highly likely, that $ARGS{edit_item} is a scalar containing the string "1".

    The complaint would be that you are attempting to dereference an array by sticking @{...} around the scalar item.

    You can confirm whether this is the case by commenting out the (potentially) offending code, and replacing it with:

    { use Data::Dumper; $m->out( '<pre>' . Dumper( \%ARGS ) . '</pre>' ); }
Re: can't use string as an array ref....
by monarch (Priest) on Jul 13, 2005 at 00:35 UTC
    So, after looking at your code, I'm guessing what you want is to process a form that looks something like
    <input type="text" name="edit_name_1" value="hello" size="20"> <input type="text" name="edit_name_2" value="world" size="20"> <input type="text" name="edit_name_3" value="form" size="20">
    ..where you have a number of edit_name_n fields.

    I suggest you do the following:

    foreach my $key ( keys %ARGS ) { # skip any arguments that aren't of interest next if ( $key !~ m/^edit_name_(\d+)$/ ); my $num = $1; # captured from the regexp my $name = $ARGS{$key}; $m->out( "<p>Edit field $num = $name</p>" ); }
      monarch has a nice, clean and safe proposal.

      The only thing I'd suggest is a sort befor keys, so that you get the edits in order.

           "Income tax returns are the most imaginative fiction being written today." -- Herman Wouk

      That works really great, thank you! I have more than one field (I simplified it for the sake of easy duplication), so besides edit_name_N I may have edit_type_N, what is the best way to work that in too? Another "next if" won't work, and when I just do an if it gives me everything posted.

      Thanks a ton! I like this way better than the other way from the other node I think.


      Michael Jensen
        There are numerous ways of approaching this. Two suggestions are:
        foreach my $key ( keys %ARGS ) { if ( $key =~ m/^edit_name_(\d+)$/ ) { my $num = $1; # captured from the regexp my $name = $ARGS{$key}; $m->out( "<p>Edit name $num = $name</p>" ); } elsif ( $key =~ m/^edit_type_(\d+)$/ ) { my $num = $1; # captured from the regexp my $type = $ARGS{$key}; $m->out( "<p>Edit type $num = $type</p>" ); } }

        The second method is to generate hashes to play with:

        my %edit_name = (); my %edit_type = (); foreach my $key ( keys %ARGS ) { if ( $key =~ m/^edit_name_(\d+)$/ ) { $edit_name{$1} = $ARGS{$key}; } elsif ( $key =~ m/^edit_type_(\d+)$/ ) { $edit_type{$1} = $ARGS{$key}; } } # play with values foreach my $num ( sort { $a <=> $b } keys %edit_name ) { $m->out( "<br />Name number $num is " . $edit_name{$num} ); } foreach my $num ( sort { $a <=> $b } keys %edit_type ) { $m->out( "<br />Type number $num is " . $edit_type{$num} ); }

        Of course the name and type might be related! In which case you might consider the following:

        my %edit = (); foreach my $key ( keys %ARGS ) { if ( $key =~ m/^edit_([^_]+)_(\d+)$/ ) { $edit{$2}->{$1} = $ARGS{$key}; } } # now %edit contains a hash of rows. In each row # is the type and name fields. e.g. # %edit = ( 1 => { name => 'John', type => 'student' }, # 2 => { name => 'Lisa', type => 'teacher' } # ); $m->out( "<table>" ); foreach my $row ( sort { $a <=> $b } keys %edit ) { if ( ! ( exists( $edit{$row}->{name} && exists( $edit{$row}->{type} ) ) { die( "Missing field for row $row" ); } $m->out( "<tr><td>" . $edit{$row}->{name} . "</td>" . "<td> . $edit{$row}->{type} . "</td></tr>" ); } $m->out( "</table>" );

        updated: cleaned up code

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://474421]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-03-29 10:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found