[SPOILER] Re: New Quiz: "What does this code do?" (1-December-2006)
Shlomi Fish <shlomif-ik1l9ssToec+JF/[email protected]> Thu, 14 Dec 2006 05:13:03 +0200
| Newsgroups | gmane.comp.lang.perl.qotw.discuss |
|---|---|
| Message-ID | <[email protected]> |
Hello to everybody,
it's been almost two weeks since this quiz was posted and I neglected to post
a spoiler as I've been unfortunately distracted by other things. Thanks to
everyone who submitted me a solution for this problem.
Now let's go over the code.
On Friday 01 December 2006 16:35, Shlomi Fish wrote:
> Hi all!
>
> Well, it's been a while since we had a quiz so here's another what does
> this code do quiz:
>
> {{{{{{
> my (@list) =
> (
> grep { $cgi->param("$prefix$_") }
> map { /^${prefix}(\d+)$/ ? ($1) : () }
> $cgi->param()
> );
> }}}}}}
$cgi->param() in list context returns a list of all CGI parameter "NAME"s. The
map part matches against a regex which matches a prefix string followed by
digits. If a NAME matches the retgex the digit part is extracted, and if
doesn't, it is skipped.
The grep makes sure the $cgi->param() of the original NAME (with the prefix
back on) is true.
This was used in an HTML form where there was a checkbox with a certain prefix
for every ID:
<<<<<
<input type="checkbox" name="toggle_1" />
<input type="checkbox" name="toggle_2" />
<input type="checkbox" name="toggle_3" />
.
.
.
>>>>>
And this snippet was used to extract the IDs that were checked.
Now for some interesting input from the solvers:
1. Ronald J. Kimball suggested using the following snippet instead:
<<<<<<<<
my(@list) =
(
map { /^${prefix}(\d+)$/ && $cgi->param($_) ? $1 : () }
$cgi->param()
);
>>>>>>>>
When I said that $1 may be destroyed by the param method call, he noted that
$1 was locally scoped, which indeed seems to be the case. So my code should
be written like that instead.
2. Peter Haworth correctly detected the use that I made of the code and
suggested using a checkbox group instead:
<<<
<input type="checkbox" name="toggle" value="1" />
<input type="checkbox" name="toggle" value="2" />
<input type="checkbox" name="toggle" value="3" />
Etc.
>>>
And then just say <<< my @list = $cgi->param("toggle"); >>>.
He also suggested the following alternative code:
<<<<<<<<<
my @list=grep /\A$prefix\d+\z/ && $cgi->param($_),$cgi->param;
s/\A$prefix// for @list;
>>>>>>>>>
3. Some people suggested the following wrong codes. Can you detect why they
are wrong?
<<<<
my @list
= grep { /^$prefix(\d+)$/ && $cgi->param("$prefix$1") }
$cgi->param();
>>>>
<<<<
my @list = map { $cgi->param( $_ ) }
grep { /^$prefix(?:\d+)?$/ }
$cgi->param();
>>>>
<<<<
my @list = grep { /^${prefix}(\d+)$/ && $cgi->param($_) } $cgi->param();
>>>>
4. Many people wrongly believed that @list returns the NAMES along with the
prefix instead of just the IDs.
--------------
Well, this was fun quiz, and I enjoyed reading your answers. Those who sent a
reply to me in private may be interested in forwarding it to the list.
If anyone has an idea for a quiz, he or she should feel free to send it to the
list.
Regards,
Shlomi Fish
---------------------------------------------------------------------
Shlomi Fish shlomif-ik1l9ssToec+JF/[email protected]
Homepage: http://www.shlomifish.org/
Chuck Norris wrote a complete Perl 6 implementation in a day but then
destroyed all evidence with his bare hands, so no one will know his secrets.