[Bps-public-commit] Path-Dispatcher branch, master, updated. ccaa6656d9a68938eb2e3ba84ccde6d12c2669d8

sartak at bestpractical.com sartak at bestpractical.com
Thu Jan 7 15:06:09 EST 2010


The branch, master has been updated
       via  ccaa6656d9a68938eb2e3ba84ccde6d12c2669d8 (commit)
      from  fbfe06cf447e1355a322377bd8f327188bed735b (commit)

Summary of changes:
 lib/Path/Dispatcher/Rule/Sequence.pm |   70 ++++++++++++++++++++++------------
 t/024-sequence.t                     |   14 +------
 2 files changed, 46 insertions(+), 38 deletions(-)

- Log -----------------------------------------------------------------
commit ccaa6656d9a68938eb2e3ba84ccde6d12c2669d8
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Jan 7 15:05:55 2010 -0500

    Make Sequence more tokeney

diff --git a/lib/Path/Dispatcher/Rule/Sequence.pm b/lib/Path/Dispatcher/Rule/Sequence.pm
index 209eaae..2171fbb 100644
--- a/lib/Path/Dispatcher/Rule/Sequence.pm
+++ b/lib/Path/Dispatcher/Rule/Sequence.pm
@@ -1,6 +1,5 @@
 package Path::Dispatcher::Rule::Sequence;
 use Any::Moose;
-use Any::Moose '::Util::TypeConstraints';
 
 extends 'Path::Dispatcher::Rule';
 with 'Path::Dispatcher::Role::Rules';
@@ -11,47 +10,68 @@ has delimiter => (
     default => ' ',
 );
 
-sub BUILD {
+sub _match_as_far_as_possible {
     my $self = shift;
-    my @rules = $self->rules;
+    my $path = shift;
 
-    # the last rule only needs to be prefix if this entire sequence is prefix
-    if (!$self->prefix) {
-        pop @rules;
-    }
+    my @tokens = $self->tokenize($path->path);
+    my @rules  = $self->rules;
+    my @matched;
+
+    while (@tokens && @rules) {
+        my $rule  = $rules[0];
+        my $token = $tokens[0];
+
+        last unless $rule->match($path->clone_path($token));
 
-    for (@rules) {
-        $_->prefix or confess "$_ is not prefix. Better diagnostics forthcoming.";
+        push @matched, $token;
+        shift @rules;
+        shift @tokens;
     }
+
+    return (\@matched, \@tokens, \@rules);
 }
 
 sub _match {
     my $self = shift;
     my $path = shift;
 
-    my @rules = $self->rules;
-    my $delimiter = $self->delimiter;
-    my @matches;
-    my $leftover = $path->path; # start with everything leftover
+    my ($matched, $tokens, $rules) = $self->_match_as_far_as_possible($path);
+
+    return if @$rules; # didn't provide everything necessary
+    return if @$tokens && !$self->prefix; # had tokens left over
 
-    for my $rule (@rules) {
-        my $match = $rule->match($path);
-        return if !$match;
+    my $leftover = $self->untokenize(@$tokens);
+    return $matched, $leftover;
+}
 
-        $leftover = $match->leftover;
+sub complete {
+    my $self = shift;
+    my $path = shift;
 
-        push @matches, substr($path, 0, length($path) - length($leftover));
+    my ($matched, $tokens, $rules) = $self->_match_as_far_as_possible($path);
+    return if @$tokens > 1; # had tokens leftover
+    return if !@$rules; # consumed all rules
 
-        $leftover =~ s/^\Q$delimiter\E+//;
-        return \@matches if length($leftover) == 0;
+    my $rule = shift @$rules;
+    my $token = @$tokens ? shift @$tokens : '';
 
-        $path = $path->clone_path($leftover);
-    }
+    return $rule->complete($token);
+}
 
-    # leftover text
-    return \@matches, $leftover if $self->prefix;
+sub tokenize {
+    my $self = shift;
+    my $path = shift;
+    return grep { length } split $self->delimiter, $path;
+}
 
-    return;
+sub untokenize {
+    my $self   = shift;
+    my @tokens = @_;
+    return join $self->delimiter,
+           grep { length }
+           map { split $self->delimiter, $_ }
+           @tokens;
 }
 
 1;
diff --git a/t/024-sequence.t b/t/024-sequence.t
index cbf0cd0..6cc0b9e 100644
--- a/t/024-sequence.t
+++ b/t/024-sequence.t
@@ -12,11 +12,9 @@ $dispatcher->add_rule(
         rules => [
             Path::Dispatcher::Rule::Eq->new(
                 string => 'foo',
-                prefix => 1,
             ),
             Path::Dispatcher::Rule::Eq->new(
                 string => 'bar',
-                prefix => 1,
             ),
         ],
         block  => sub { push @calls, [$1, $2, $3] },
@@ -31,7 +29,6 @@ $dispatcher->add_rule(
         rules => [
             Path::Dispatcher::Rule::Eq->new(
                 string => 'foo',
-                prefix => 1,
             ),
             Path::Dispatcher::Rule::Regex->new(
                 regex => qr/bar/,
@@ -48,7 +45,7 @@ $dispatcher->run('foo barbaz');
 is_deeply([splice @calls], [ ['foo', 'barbaz', undef] ], "ran the second [str, regex] rule");
 
 $dispatcher->run('foo bar baz');
-is_deeply([splice @calls], [ ['foo', 'bar baz', undef] ], "no matches");
+is_deeply([splice @calls], [ ], "no matches");
 
 $dispatcher->add_rule(
     Path::Dispatcher::Rule::Sequence->new(
@@ -57,14 +54,11 @@ $dispatcher->add_rule(
                 rules => [
                     Path::Dispatcher::Rule::Eq->new(
                         string => 'Bat',
-                        prefix => 1,
                     ),
                     Path::Dispatcher::Rule::Eq->new(
                         string => 'Super',
-                        prefix => 1,
                     ),
                 ],
-                prefix => 1,
             ),
             Path::Dispatcher::Rule::Eq->new(
                 string => 'Man',
@@ -87,17 +81,13 @@ $dispatcher->add_rule(
     Path::Dispatcher::Rule::Sequence->new(
         rules => [
             Path::Dispatcher::Rule::Alternation->new(
-                prefix => 1,
                 rules => [
                     Path::Dispatcher::Rule::Alternation->new(
-                        prefix => 1,
                         rules => [
                             Path::Dispatcher::Rule::Alternation->new(
-                                prefix => 1,
                                 rules => [
                                     Path::Dispatcher::Rule::Regex->new(
                                         regex => qr/Deep/,
-                                        prefix => 1,
                                     ),
                                 ],
                             ),
@@ -124,12 +114,10 @@ my $rule = Path::Dispatcher::Rule::Sequence->new(
         Path::Dispatcher::Rule::Eq->new(
             string         => 'path',
             case_sensitive => 0,
-            prefix         => 1,
         ),
         Path::Dispatcher::Rule::Eq->new(
             string         => 'dispatcher',
             case_sensitive => 0,
-            prefix         => 1,
         ),
     ],
     prefix    => 1,

-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list