[Bps-public-commit] r14639 - in Path-Dispatcher/trunk: lib/Path lib/Path/Dispatcher t
sartak at bestpractical.com
sartak at bestpractical.com
Wed Jul 30 12:19:55 EDT 2008
Author: sartak
Date: Wed Jul 30 12:19:52 2008
New Revision: 14639
Added:
Path-Dispatcher/trunk/t/007-coderef-matcher.t
Modified:
Path-Dispatcher/trunk/ (props changed)
Path-Dispatcher/trunk/lib/Path/Dispatcher.pm
Path-Dispatcher/trunk/lib/Path/Dispatcher/Rule.pm
Log:
r68010 at onn: sartak | 2008-07-30 12:19:40 -0400
Support for arbitrary dispatch matching with coderefs (so we can support Jifty::Dispatcher's "when" rule type)
Modified: Path-Dispatcher/trunk/lib/Path/Dispatcher.pm
==============================================================================
--- Path-Dispatcher/trunk/lib/Path/Dispatcher.pm (original)
+++ Path-Dispatcher/trunk/lib/Path/Dispatcher.pm Wed Jul 30 12:19:52 2008
@@ -54,8 +54,8 @@
or next;
push @matches, {
- rule => $rule,
- vars => $vars,
+ rule => $rule,
+ result => $vars,
};
last if !$rule->fallthrough;
@@ -83,10 +83,16 @@
eval {
local $SIG{__DIE__} = 'DEFAULT';
for my $match (@$matches) {
- $self->run_with_number_vars(
- sub { $match->{rule}->run($path) },
- @{ $match->{vars} },
- );
+ # if we need to set $1, $2..
+ if (ref($match->{result}) eq 'ARRAY') {
+ $self->run_with_number_vars(
+ sub { $match->{rule}->run($path) },
+ @{ $match->{result} },
+ );
+ }
+ else {
+ $match->{rule}->run($path);
+ }
}
};
Modified: Path-Dispatcher/trunk/lib/Path/Dispatcher/Rule.pm
==============================================================================
--- Path-Dispatcher/trunk/lib/Path/Dispatcher/Rule.pm (original)
+++ Path-Dispatcher/trunk/lib/Path/Dispatcher/Rule.pm Wed Jul 30 12:19:52 2008
@@ -9,9 +9,9 @@
required => 1,
);
-has regex => (
+has matcher => (
is => 'ro',
- isa => 'Regexp',
+ isa => 'CodeRef',
required => 1,
);
@@ -31,14 +31,53 @@
},
);
+around BUILDARGS => sub {
+ my $orig = shift;
+ my $self = shift;
+ my $args = $self->$orig(@_);
+
+ if (!$args->{matcher} && $args->{regex}) {
+ $args->{matcher} = $self->build_regex_matcher(delete $args->{regex});
+ }
+
+ return $args;
+};
+
+sub build_regex_matcher {
+ my $self = shift;
+ my $re = shift;
+
+ # compile the regex immediately, instead of each match
+ $re = qr/$re/;
+
+ return sub {
+ return unless $_ =~ $re;
+
+ my $path = $_;
+ return [ map { substr($path, $-[$_], $+[$_] - $-[$_]) } 1 .. $#- ];
+ }
+}
+
sub match {
my $self = shift;
my $path = shift;
- return unless $path =~ $self->regex;
+ local $_ = $path;
+ my $result = $self->matcher->();
+ return unless $result;
+
+ # make sure that the returned values are PLAIN STRINGS
+ # later we will stick them into a regular expression to populate $1 etc
+ # which will blow up later!
+
+ if (ref($result) eq 'ARRAY') {
+ for (@$result) {
+ die "Invalid result '$_', results must be plain strings"
+ if ref($_);
+ }
+ }
- # return [$1, $2, $3, ...]
- return [ map { substr($path, $-[$_], $+[$_] - $-[$_]) } 1 .. $#- ]
+ return $result;
}
sub run {
Added: Path-Dispatcher/trunk/t/007-coderef-matcher.t
==============================================================================
--- (empty file)
+++ Path-Dispatcher/trunk/t/007-coderef-matcher.t Wed Jul 30 12:19:52 2008
@@ -0,0 +1,19 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More tests => 2;
+use Path::Dispatcher;
+
+my (@matches, @calls);
+
+my $dispatcher = Path::Dispatcher->new;
+$dispatcher->add_rule(
+ matcher => sub { push @matches, $_; length > 5 },
+ block => sub { push @calls, [@_] },
+);
+
+$dispatcher->run('foobar');
+
+is_deeply([splice @matches], ['foobar']);
+is_deeply([splice @calls], [ [] ]);
+
More information about the Bps-public-commit
mailing list