Wednesday, July 14, 2010

Catalyst $c->req->params sucks

Catalyst has added parameters() to its Catalyst::Request object and it allows you to get values in an array ref if there are multiple.



my $form = $c->request->parameters;

# ?a=b&b=c
# $form = { a => 'b', b => 'c' }
# ?a=b&a=c&b=c
# $form = { a => [ 'b', 'c' ], b => 'c' };



This might look intuitive but wait a minute. The data structure gets different per user input rather than how you code it, and that sucks. This means you have to always check if the value is an array ref or not, since:



my $v = $c->request->parameters;
my $query = $v->{query};
my @names = @{$v->{name}};



$query might become ARRAY(0xabcdef) if there are multiple query= parameters in the query. @names line might cause Can't use string as an ARRAY ref error if there's only one (or zero) name parameter. This causes horrible issues when using standard HTML elements like option or checkbox forms, or tools like jQuery's serialize().

The correct way to write that would be:



my $v = $c->request->parameters;
my $query = ref $v->{query} eq 'ARRAY' ? $v->{query}->[0] : $v->{query};
my @names = ref $v->{name} eq 'ARRAY' ? @{$v->{name}} : ($v->{name});



and it is tedious and gross.

No comments:

Post a Comment