[Bps-public-commit] Path-Dispatcher branch, named_captures, updated. 62822641333e685e3534102653d80dcc95e1438e

Shawn Moore sartak at bestpractical.com
Thu Jun 24 15:08:18 EDT 2010


The branch, named_captures has been updated
       via  62822641333e685e3534102653d80dcc95e1438e (commit)
      from  0c9f01e08aa344f091945d0e5968e195268064b6 (commit)

Summary of changes:
 lib/Path/Dispatcher/Match.pm         |   57 +++++++++++++---------------------
 lib/Path/Dispatcher/Rule.pm          |   13 +-------
 lib/Path/Dispatcher/Rule/Regex.pm    |    9 ++++-
 lib/Path/Dispatcher/Rule/Sequence.pm |    4 ++-
 lib/Path/Dispatcher/Rule/Tokens.pm   |    4 ++-
 t/002-rule.t                         |    2 +-
 t/007-coderef-matcher.t              |    2 +-
 t/014-tokens-prefix.t                |    2 +-
 t/015-regex-prefix.t                 |    2 +-
 t/022-numbers-undef.t                |    2 +-
 t/901-return-values.t                |   19 -----------
 11 files changed, 41 insertions(+), 75 deletions(-)
 delete mode 100644 t/901-return-values.t

- Log -----------------------------------------------------------------
commit 62822641333e685e3534102653d80dcc95e1438e
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Jun 24 15:08:14 2010 -0400

    Refactor results into positional_captures and named_captures

diff --git a/lib/Path/Dispatcher/Match.pm b/lib/Path/Dispatcher/Match.pm
index 06be61d..1dbe143 100644
--- a/lib/Path/Dispatcher/Match.pm
+++ b/lib/Path/Dispatcher/Match.pm
@@ -21,15 +21,16 @@ has rule => (
     required => 1,
 );
 
-has result => (
-    is => 'rw',
+has positional_captures => (
+    is      => 'ro',
+    isa     => 'ArrayRef',
+    default => sub { [] },
 );
 
-has set_number_vars => (
-    is      => 'rw',
-    isa     => 'Bool',
-    lazy    => 1,
-    default => sub { ref(shift->result) eq 'ARRAY' },
+has named_captures => (
+    is      => 'ro',
+    isa     => 'HashRef',
+    default => sub { {} },
 );
 
 sub run {
@@ -38,28 +39,26 @@ sub run {
 
     local $_ = $self->path;
 
-    if ($self->set_number_vars) {
-        return $self->run_with_number_vars(
-            sub { $self->rule->run(@args) },
-            @{ $self->result },
-        );
-    }
-
-    return $self->rule->run(@args);
+    return $self->_run_with_capture_vars(
+        sub { $self->rule->run(@args) },
+    );
 }
 
-sub run_with_number_vars {
+sub _run_with_capture_vars {
     my $self = shift;
     my $code = shift;
 
-    # clear $1, $2, $3 so they don't pollute the number vars for the block
+    # clear $1, $2, $3, %+ so they don't pollute the number vars for the block
     "x" =~ /x/;
 
     # populate $1, $2, etc for the duration of $code
     # it'd be nice if we could use "local" but it seems to break tests
     my $i = 0;
     no strict 'refs';
-    *{ ++$i } = \$_ for @_;
+    *{ ++$i } = \$_ for @{ $self->positional_captures };
+
+    # populate %+
+    *% = $self->named_captures;
 
     $code->();
 }
@@ -84,14 +83,12 @@ Path::Dispatcher::Match - the result of a successful rule match
 
     my $match = $rule->match("attack dragon");
 
-    $match->path            # "attack dragon"
-    $match->leftover        # empty string (populated with prefix rules)
-    $match->rule            # $rule
-    $match->result          # ["attack", "dragon"] (decided by the rule)
-    $match->set_number_vars # 1 (boolean indicating whether to set $1, $2, etc)
+    $match->path             # "attack dragon"
+    $match->leftover         # empty string (populated with prefix rules)
+    $match->rule             # $rule
 
-    $match->run                         # causes the player to attack the dragon
-    $match->run_with_number_vars($code) # runs $code with $1=attack $2=dragon
+    $match->run                          # causes the player to attack the dragon
+    $match->run_with_capture_vars($code) # runs $code with $1=attack $2=dragon
 
 =head1 DESCRIPTION
 
@@ -113,16 +110,6 @@ The path that the rule matched.
 The rest of the path. This is populated when the rule matches a prefix of the
 path.
 
-=head2 result
-
-Arbitrary results generated by the rule. For example, L<Path::Dispatcher::Rule::Regex> rules' result is an array reference of capture variables.
-
-=head2 set_number_vars
-
-A boolean indicating whether invoking the rule should populate the number variables (C<$1>, C<$2>, etc) with the array reference of results.
-
-Default is true if the C<result> is an array reference; otherwise false.
-
 =head1 METHODS
 
 =head2 run
diff --git a/lib/Path/Dispatcher/Rule.pm b/lib/Path/Dispatcher/Rule.pm
index 5e384cb..4eab217 100644
--- a/lib/Path/Dispatcher/Rule.pm
+++ b/lib/Path/Dispatcher/Rule.pm
@@ -44,22 +44,11 @@ sub match {
 
     $leftover = '' if !defined($leftover);
 
-    # 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($_);
-        }
-    }
-
     my $match = $self->match_class->new(
         path     => $path,
         rule     => $self,
-        result   => $result,
         leftover => $leftover,
+        (ref $result eq 'HASH') ? %$result : (),
     );
 
     $self->trace(match => $match) if $ENV{'PATH_DISPATCHER_TRACE'};
diff --git a/lib/Path/Dispatcher/Rule/Regex.pm b/lib/Path/Dispatcher/Rule/Regex.pm
index baec99a..77bdd43 100644
--- a/lib/Path/Dispatcher/Rule/Regex.pm
+++ b/lib/Path/Dispatcher/Rule/Regex.pm
@@ -14,13 +14,18 @@ sub _match {
 
     return unless my @matches = $path->path =~ $self->regex;
 
+    my $results = {
+        positional_captures => \@matches,
+        named_captures      => \%+,
+    };
+
     # if $' is in the program at all, then it slows down every single regex
     # we only want to include it if we have to
     if ($self->prefix) {
-        return \@matches, eval q{$'};
+        return $results, eval q{$'};
     }
 
-    return \@matches;
+    return $results;
 }
 
 sub readable_attributes { shift->regex }
diff --git a/lib/Path/Dispatcher/Rule/Sequence.pm b/lib/Path/Dispatcher/Rule/Sequence.pm
index 7cdc213..df6c279 100644
--- a/lib/Path/Dispatcher/Rule/Sequence.pm
+++ b/lib/Path/Dispatcher/Rule/Sequence.pm
@@ -42,7 +42,9 @@ sub _match {
     return if @$tokens && !$self->prefix; # had tokens left over
 
     my $leftover = $self->untokenize(@$tokens);
-    return $matched, $leftover;
+    return {
+        positional_captures => $matched,
+    }, $leftover;
 }
 
 sub complete {
diff --git a/lib/Path/Dispatcher/Rule/Tokens.pm b/lib/Path/Dispatcher/Rule/Tokens.pm
index dfbd05d..8bbb090 100644
--- a/lib/Path/Dispatcher/Rule/Tokens.pm
+++ b/lib/Path/Dispatcher/Rule/Tokens.pm
@@ -53,7 +53,9 @@ sub _match {
     return if @$got && !$self->prefix; # had tokens left over
 
     my $leftover = $self->untokenize(@$got);
-    return $matched, $leftover;
+    return {
+        positional_captures => $matched,
+    }, $leftover;
 }
 
 sub complete {
diff --git a/t/002-rule.t b/t/002-rule.t
index 3bc94e7..13327be 100644
--- a/t/002-rule.t
+++ b/t/002-rule.t
@@ -17,7 +17,7 @@ my $rule = Path::Dispatcher::Rule::Regex->new(
 );
 
 isa_ok($rule->match(Path::Dispatcher::Path->new('foobar')), 'Path::Dispatcher::Match');
-is_deeply($rule->match(Path::Dispatcher::Path->new('foobar'))->result, ['fo', 'ob']);
+is_deeply($rule->match(Path::Dispatcher::Path->new('foobar'))->positional_captures, ['fo', 'ob']);
 is_deeply([splice @calls], [], "block not called on match");
 
 $rule->run;
diff --git a/t/007-coderef-matcher.t b/t/007-coderef-matcher.t
index 8823c9a..8f33fb8 100644
--- a/t/007-coderef-matcher.t
+++ b/t/007-coderef-matcher.t
@@ -9,7 +9,7 @@ my (@matches, @calls);
 my $dispatcher = Path::Dispatcher->new;
 $dispatcher->add_rule(
     Path::Dispatcher::Rule::CodeRef->new(
-        matcher => sub { push @matches, $_; length > 5 },
+        matcher => sub { push @matches, $_; { positional_captures => [length > 5] } },
         block   => sub { push @calls, [@_] },
     ),
 );
diff --git a/t/014-tokens-prefix.t b/t/014-tokens-prefix.t
index 962a82c..a263bcb 100644
--- a/t/014-tokens-prefix.t
+++ b/t/014-tokens-prefix.t
@@ -17,6 +17,6 @@ ok($rule->match(Path::Dispatcher::Path->new('foo bar')), "prefix matches the ful
 
 my $match = $rule->match(Path::Dispatcher::Path->new('foo bar baz'));
 ok($match, "prefix matches a prefix of the path");
-is_deeply($match->result, ["foo", "bar"]);
+is_deeply($match->positional_captures, ["foo", "bar"]);
 is($match->leftover, "baz");
 
diff --git a/t/015-regex-prefix.t b/t/015-regex-prefix.t
index 0ae9f94..eae193c 100644
--- a/t/015-regex-prefix.t
+++ b/t/015-regex-prefix.t
@@ -19,6 +19,6 @@ my $match = $rule->match(Path::Dispatcher::Path->new('foobar:baz'));
 
 ok($match, "matched foobar:baz");
 
-is_deeply($match->result, ["foo", "bar"], "match returns just the results");
+is_deeply($match->positional_captures, ["foo", "bar"], "match returns just the results");
 is($match->leftover, ':baz', "leftovers");
 
diff --git a/t/022-numbers-undef.t b/t/022-numbers-undef.t
index d4eff58..756dad8 100644
--- a/t/022-numbers-undef.t
+++ b/t/022-numbers-undef.t
@@ -13,7 +13,7 @@ my $rule = Path::Dispatcher::Rule::Regex->new(
 );
 
 my $match = $rule->match(Path::Dispatcher::Path->new("foobaz"));
-is_deeply($match->result, ['foo', undef, 'baz']);
+is_deeply($match->positional_captures, ['foo', undef, 'baz']);
 
 $match->run;
 is_deeply(\@recaptures, ['foo', undef, 'baz']);
diff --git a/t/901-return-values.t b/t/901-return-values.t
deleted file mode 100644
index 5822f7b..0000000
--- a/t/901-return-values.t
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-use Test::More tests => 1;
-use Test::Exception;
-use Path::Dispatcher;
-
-my $dispatcher = Path::Dispatcher->new(
-    rules => [
-        Path::Dispatcher::Rule::CodeRef->new(
-            matcher => sub { [{ cant_handle_complex_list_of_results => 1 }] },
-        ),
-    ],
-);
-
-throws_ok {
-    $dispatcher->dispatch('foo');
-} qr/Invalid result 'HASH\(\w+\)', results must be plain strings/;
-

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



More information about the Bps-public-commit mailing list