in reply to Mapping URLs to code - in search of perlish dispatch schemes

Sounds great!

The following (not very carefully considered) thoughts spring to mind...

Would you consider making it more generic, and not tied specifically to CGI? It might be nice to have in a mod_perl handler too, where we might assume $r instead of $q, and any other variations as well.

If you do this, you would no doubt create a base despatch and validation class, and then specialise this to provide natural args in each environment - e.g. a CGI implementation would provide natural CGI args, and a mod_perl method would provide the request handle $r etc.

The subs will probably need standardised, but more complex arg handling - how about something like:

/edit?items=[(\w+)];location=(\w+);flags={(\d+)};... { if ( $arg->{location} eq 'US' ) { for my $item ( @{$arg->{items}} ) { if ( $arg->{flags}{54} ) { $r->print "item: $item qualifies for discount 54 processing< +br>\n"; } } } # other optional args that we may / may not have if ( defined $arg->{style} ) { $r->print("you have style! $arg->{style}<br>\n" } }; # args are placed in hashref $arg # [] indicates that the named arg should be an array. # {} indicates that the named arg should be a hash. # for a URL of flags=54&amp;flags=23&amp;flags=red # might yeild # $arg->{flags} = { # 54 => 54, # 23 => 23, # red => 'red', # }; # so that programmers can use keys values as they are comfy? # optional args (ie the ...) are available in $arg
On validation of params, you might consider an additional section for validation subs for the named args
:DESPATCH /edit?node=(\w+);... { print "You're trying to edit '$node'"; }; :PARAM node { my ( $node ) = @_; my $db = My::Database->new(...); return $node if $db->selectValue( sql => "select count(*) from nod +es where node=?", param => [$node] ); print "invalid node: $node"; return undef; }

The despatch fall-through case /(.*) should probably be handled by the despatch class, by default - it will have to do something if nothing matches!

You will also have to resolve conflicts where a URL matches more than one sub

/edit?name=(\w+);city=(\w+);... { print "Edit '$name' in '$city'"; }; /edit?name=(\w+);job=(.*);... { print "Edit '$name' who does '$job'"; };

Various approaches spring to mind, generally the most specific wins, but if the despatch matches are equally specific?

Regards,

Jeff