Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

form parsing

by Rotomola (Initiate)
on Oct 09, 2001 at 13:29 UTC ( [id://117679]=perlquestion: print w/replies, xml ) Need Help??

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

Okay, this is probably a really simple question but heres what I'm doing. I'm writing a script that will parse a form using cgi.pm (first time using cgi.pm to parse a form, don't laugh). What I would like to do is filter out ceratin characters from all fields. The only way I can get this to work now is something like
$cgi->param('field1') =~ s/[\*]//g; $cgi->param('field2') =~ s/[\*]//g;
....and so on. Isn't there a way to do this with one line of code?

Replies are listed 'Best First'.
Re: form parsing
by davorg (Chancellor) on Oct 09, 2001 at 13:36 UTC

    How about something like this:

    $cgi->param($_) =~ tr/*//d foreach $cgi->param;

    Note that I've switched to using tr for removing characters.

    The code becomes even easier if you use the functional interface to CGI.pm:

    param($_) =~ tr/*//d foreach param;

    Update: Of course, merlyn's point below is right. This code was never going to work. CGI::param doesn't return an lvalue, so you cant' assign to it. Use the code that he proposes instead.

    I wonder if all the people who voted this node up had actually tried the code :)

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

Re: form parsing
by merlyn (Sage) on Oct 09, 2001 at 18:01 UTC
    Your code won't work, and neither will any of the responses so far, for the simple matter that $cgi->param doesn't return an lvalue!

    Try this instead:

    for my $p (qw(field1 field2)) { local $_ = $cgi->param($p); s/\*//g; # or tr/*//d; $cgi->param($p, $_); # set it back }

    -- Randal L. Schwartz, Perl hacker

      Now that we have somewhat functional code, it is still broken for two reasons.

      The first has to do with CGI's attempts to overload the param function with every possible behaviour. What happens if your form has an input variable named "-name"?

      The second has to do with Perl's list versus scalar context. What happens if your form sent back multiple values with the same name?

      Here is more robust code, using the functional interface (easily translated into the OO interface):

      foreach my $name (param()) { my @values = param($p); s/\*//g foreach @values; param( -name=>$name, -values=>\@values ); }
      And people wonder why I prefer to avoid creating highly magical polymorphic interfaces? Note between merlyn and myself in 8 lines of code, with 5 different invocations of the param function, no two of them used the same part of the possible interface! (This is even true if you don't count the OO vs functional invocation issue.) People handle context pretty well, true, but there is a limit beyond which people start having problems. And when you mess up for this reason, it isn't very obvious that you did mess up, or what you did wrong!
Re: form parsing
by htoug (Deacon) on Oct 09, 2001 at 13:36 UTC
    You could do something like:
    for (qw!field1 field2!) { $cgi->param($_) =~ s/\*//g; }
    but thats 3 lines...
    Update Beaten to it by davorg again. Gr...
Re: form parsing
by arturo (Vicar) on Oct 09, 2001 at 18:55 UTC

    Assuming your input is well-behaved, you might pop all of it into a hash with something as simple as

    # updated -- davorg noticed that $-> ... should be $_=> my %input = map { $_=>$cgi->param($_) } $cgi->param();

    Warning: this won't work if you have multiple fields with the same name (that returns a list, not a scalar, as this code assumes -- if this is an issue, it can be dealt with, but I'll assume the simple case). Alternately, you can use the backwards-compatbility ReadParse function:

    CGI::ReadParse(); # input values now in hash named "%in"

    Anyhow, once it's all into the hash, you can do a

    foreach my $key (keys %input) { $input{$key} =~ tr/*//d; # or whatever makes sense }

    HTH.

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
      my %input = map { $_->$cgi->param($_) } $cgi->param();
      can be written as:
      my %input = map { $_ => scalar $cgi->param($_) } $cgi->param();
      to fix the possible "multiple value" problem, for some version of "fix". (Your arrow was wrong, by the way.)
      foreach my $key (keys %input) { $input{$key} =~ tr/*//d; # or whatever makes sense }
      can be written as:
      tr/*//d for values %input;
      for recent versions of Perl.

      -- Randal L. Schwartz, Perl hacker

Re: form parsing
by jeroenes (Priest) on Oct 09, 2001 at 13:40 UTC
    For a blessfull change, try to use the CODE tag.

    Second, read the docs, eg CGI.

    Than, your code can be shuffled into:

    for my $field ($cgi->param){ $cgi->param($field) =~ s/search/replace/g; }

    Try subsequently to rethink your regexes...

    Jeroen
    "We are not alone"(FZ)

    Update /me humbly crawls in the dust, ashamed of the mere suggestion, let alone the naked fact, of the use of $cgi->param as an l-value. I just was not thinking, that's the only thing I can come up with. That's not even an excuse. As a self-proclaimed punishment:

    open LETEVERYBODYKNOW, ">/var/www/index.html"; print LETEVERYBODYKNOW "Thou shall not use CGI's param as an l-val +ue\n" for 1..117682;
    I believe merlyn and tilly have some runable code, actually.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-25 17:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found