addition of first_index to the native Array trait.
Karen Etheridge [Mon, 13 Jun 2011 19:37:16 +0000 (12:37 -0700)]
Changes
lib/Moose/Meta/Attribute/Native/Trait/Array.pm
lib/Moose/Meta/Method/Accessor/Native/Array/first_index.pm [new file with mode: 0644]
t/native_traits/trait_array.t

diff --git a/Changes b/Changes
index 51b640a..da641f9 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,6 +3,11 @@ for, noteworthy changes.
 
 {{$NEXT}}
 
+  [ENHANCEMENTS]
+
+  * The native Array trait now has a 'first_index' method, which works just
+    like the version in List::MoreUtils. (Karen Etheridge)
+
 2.0101 Mon, Jun 06, 2011
 
   [OTHER]
index 29916ec..a743c4d 100644 (file)
@@ -133,7 +133,7 @@ This method requires at least one argument.
 
 =item * B<first( sub { ... } )>
 
-This method returns the first item matching item in the array, just like
+This method returns the first matching item in the array, just like
 L<List::Util>'s C<first> function. The matching is done with a subroutine
 reference you pass to this method. The subroutine will be called against each
 element in the array until one matches or all elements have been checked.
@@ -143,6 +143,16 @@ element in the array until one matches or all elements have been checked.
 
 This method requires a single argument.
 
+=item * B<first_index( sub { ... } )>
+
+This method returns the index of the first matching item in the array, just
+like L<List::MoreUtils>'s C<first_index> function. The matching is done with a
+subroutine reference you pass to this method. The subroutine will be called
+against each element in the array until one matches or all elements have been
+checked.
+
+This method requires a single argument.
+
 =item * B<grep( sub { ... } )>
 
 This method returns every element matching a given criteria, just like Perl's
diff --git a/lib/Moose/Meta/Method/Accessor/Native/Array/first_index.pm b/lib/Moose/Meta/Method/Accessor/Native/Array/first_index.pm
new file mode 100644 (file)
index 0000000..30cefd8
--- /dev/null
@@ -0,0 +1,46 @@
+package Moose::Meta::Method::Accessor::Native::Array::first_index;
+
+use strict;
+use warnings;
+
+use List::MoreUtils ();
+use Params::Util ();
+
+use Moose::Role;
+
+with 'Moose::Meta::Method::Accessor::Native::Reader' => {
+    -excludes => [
+        qw(
+            _minimum_arguments
+            _maximum_arguments
+            _inline_check_arguments
+            )
+    ]
+};
+
+sub _minimum_arguments { 1 }
+
+sub _maximum_arguments { 1 }
+
+sub _inline_check_arguments {
+    my $self = shift;
+
+    return (
+        'if (!Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to first_index must be a code reference"',
+            ) . ';',
+        '}',
+    );
+}
+
+sub _return_value {
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return '&List::MoreUtils::first_index($_[0], @{ (' . $slot_access . ') })';
+}
+
+no Moose::Role;
+
+1;
index decf151..f44d0b1 100644 (file)
@@ -53,6 +53,8 @@ use Test::Moose;
         grep_curried  => [ grep => ( sub { $_ < 5 } ) ],
         first         => 'first',
         first_curried => [ first => ( sub { $_ % 2 } ) ],
+        first_index   => 'first_index',
+        first_index_curried => [ first_index => ( sub { $_ % 2 } ) ],
         join          => 'join',
         join_curried => [ join => '-' ],
         shuffle      => 'shuffle',
@@ -523,6 +525,32 @@ sub run_tests {
             $obj->first_curried( sub { } );
         }, qr/Cannot call first with more than 1 argument/, 'throws an error when passing one argument passed to first_curried' );
 
+
+        is(
+            $obj->first_index( sub { $_ % 2 } ),
+            3,
+            'first_index returns expected value'
+        );
+
+        like( exception { $obj->first_index }, qr/Cannot call first_index without at least 1 argument/, 'throws an error when passing no arguments to first_index' );
+
+        like( exception {
+            $obj->first_index( sub { }, 2 );
+        }, qr/Cannot call first_index with more than 1 argument/, 'throws an error when passing two arguments to first_index' );
+
+        like( exception { $obj->first_index( {} ) }, qr/The argument passed to first_index must be a code reference/, 'throws an error when passing a non coderef to first_index' );
+
+        is(
+            $obj->first_index_curried,
+            3,
+            'first_index_curried returns expected value'
+        );
+
+        like( exception {
+            $obj->first_index_curried( sub { } );
+        }, qr/Cannot call first_index with more than 1 argument/, 'throws an error when passing one argument passed to first_index_curried' );
+
+
         $obj->_values( [ 1 .. 4 ] );
 
         is(