in reply to Reinventing wheels: query string parsing.

Mmmm, I look at that code and I'm really not sure what it's doing without really having to think about it. Maybe it's my aversion to for (;;) style loops but something more like this seems much more understandable to me:
my (%values, $key); foreach my $value ( split /[&;]/, $query_string ) { my ($name, $data) = split /=/, $value; if ( lc($name) eq 'o' ) { $key = $data; $values{$key} = undef unless exists $values{$key}; } elsif ( lc($name) eq 'd' and defined $key ) { # anything you need to do to $data happens here if ( ref $values{$key} eq 'ARRAY' ) { push @{$values{$key}}, $data; } elsif ( defined $values{$key} ) { $values{$key} = [ $values{$key}, $data ]; } else { $values{$key} = $data; } } }

It does throw away anything that isn't either an o or d param and any d that occurs before the first o is also thrown away but as your code also does that it seemed the thing to do.

And if you always use array refs then the second half of the d/o if statement becomes:

push @{$values{$key}}, $data;

which seems to me all the clearer.

Struan