in reply to Adding regexps to named URI parameters aka /from/:foo/to/:bar - can it get better than this?

Dallaylaen:

I agree that compact and readable are worthwhile goals. I also agree that the third goal you alluded to (but didn't state) is worthwhile--unsurprising. Until you actually build some larger cases yourself, though, it'll be a bit difficult to judge which approach best meets your goals.

I often hit the same snag and try to 'optimize' those goals before I'm ready. My suggestion would be to do one of:

Presenting the issue to us is a good idea, too, as someone may have a good suggestion, but in this case, I think I'd more fully show your alternatives so that we don't have to dream up our own test cases. The problem with letting us come up with our own internalized test cases is that it's too easy to miss cases when you're thinking of test cases rather than writing them down as an example. So working up your own examples may make it rather more obvious to you what the better approach would be. (Kinda like the debugging technique "Rubber Duck Debugging"2 "Talking to the Teddy Bear" (or whatever it was, I forget what the standard name for it is).)

Anyway, while typing this up I had the thought (dunno if it would be useful or not, or even work1) of using a quoted regex for the first get parameter (i.e., let perl do the heavy lifting), and then you could possibly let the named parameters come free from perls regex handler:

get qr/(?<greet>hi|hello)/ => sub { print $+{greet}, " there!\n"; }

Update: Added note below (and marker above).

Note 1: I haven't used named captures very often ... often enough to know they exist, but infrequently enough that I'm always having to read the documentation on them and give it a few tries before I can use with without tripping over the syntax...

Note 2: Fixed debugging method name, thanks pryrt!

Note 3: I'm off work today, and I got curious whether I could make it work or not, so I gave it a try:

$ cat pm_1198334.pl #!env perl my @handlers; sub get { my ($key, $action) = @_; push @handlers, [ $key, $action ]; } sub handle { my $request = shift; for my $rh (@handlers) { my ($key, $action) = @$rh; if ("Regexp" eq ref $key) { return $action->($request) if $request =~ $key; } elsif ("" eq ref $key) { return $action->($request) if $key eq $request; } else { print "How do I handle <", ref($key), ">?\n"; } } print "Sorry, I don't know what <$request> means!\n"; } get foo => sub { print "Pizza time!\n" }; get qr/(?<greet>hi|hello)/ => sub { print $+{greet}, " there!\n" }; handle("foo"); handle("hi robot!"); handle("helloooooooo Nurse!"); Roboticus@Waubli ~ $ perl pm_1198334.pl Pizza time! hi there! hello there!

Success!

...roboticus

When your only tool is a hammer, all problems look like your thumb.

  • Comment on Re: Adding regexps to named URI parameters aka /from/:foo/to/:bar - can it get better than this?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Adding regexps to named URI parameters aka /from/:foo/to/:bar - can it get better than this?
by pryrt (Abbot) on Aug 30, 2017 at 13:34 UTC
Re^2: Adding regexps to named URI parameters aka /from/:foo/to/:bar - can it get better than this?
by Dallaylaen (Chaplain) on Sep 11, 2017 at 09:27 UTC

    Thank you, roboticus.

    Despite my post being a case of "rubber duck debugging", my duck didn't tell me anything, so I had no choice but to submit it.

    Your answer was quite insightful though. I realized that if I used an actual regexp I would most likely use something like my ($foo, $bar) = $line =~ qr/.../; instead of named captures. I think I'll just add a method to extract unnamed captures from path_info.

    As for the use cases, IMHO mapping fancy URLs to query parameters is not at all a framework's responsibility. A proxy should do it. However, Mojo and Dancer and Kelp have it and I have to match if I want to ever take off.

    Thanks again.

      To match add dependency on standalone cpan module that does it
        Looks like Routes::Tiny does it. Hmmm, maybe I'll try it. Thanks!