MooseでList::RubyLike
List::RubyLikeをMoose::Autobox用に移植してみました。
まだ足りないメソッドはありますが、おいおい追加していきます。
コード
package Moose::Autobox::Array::RubyLike; use Moose::Role; use Moose::Autobox; use List::Util; use Carp qw/croak/; our $VERSION = '0.01'; sub find { my ( $array, $cond ) = @_; my $code = ( ref $cond and ref $cond eq 'CODE' ) ? $cond : sub { $_ eq $cond }; for (@$array) { &$code and return $_ } return; } sub delete_at { my ( $array, $pos ) = @_; my $last_index = $array->_last_index; return if $pos > $last_index; my $result; $_ == $pos ? $result = $array->shift : $array->push( $array->shift ) for 0 .. $last_index; return $result; } sub delete_if { my ( $array, $code ) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; my $last_index = $array->_last_index; for ( 0 .. $last_index ) { my $item = $array->shift; local $_ = $item; $array->push($item) if $code->($_); } return $array; } sub _last_index { my $array = CORE::shift; $array->length ? $array->length - 1 : 0; } sub each { my ( $array, $code ) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; my @copied = @{$array}; $code->($_) for @copied; $array; } sub compact { my $array = shift; $array->grep( sub {defined} ); } sub is_empty { !$_[0]->length; } sub sum { List::Util::sum @{ $_[0] }; } *collect = \↦ 1; __END__
テスト
#!/usr/bin/perl use strict; use warnings; use Test::More tests => 15; BEGIN { use_ok('Moose::Autobox'); } use Moose::Autobox; Moose::Autobox->mixin_additional_role( 'ARRAY', 'Moose::Autobox::Array::RubyLike' ); #find my $list = [ 1 .. 3 ]; is $list->find( sub { $_ == 1 } ), 1, 'contain 1'; is $list->find( sub { $_ == 2 } ), 2, 'contain 2'; is $list->find( sub { $_ == 3 } ), 3; is $list->find( sub { $_ == 4 } ), undef; is $list->find(1), 1; is $list->find(2), 2; is $list->find(3), 3; is $list->find(4), undef; # delete_at $list = [ 1, 2, 3, 4, 5 ]; ok not $list->delete_at(5); is_deeply( $list->delete_at(2), 3 ); is_deeply( $list->delete_at(0), 1 ); # delete_if $list = [ 1, 2, 3, 4, 5 ]; is_deeply( $list->delete_if( sub { $_ < 3 ? 1 : 0 } ), [ 1, 2 ] ); # each $list = [ 'foo', 'bar', 'baz' ]; my @resulsts; my $ret = $list->each( sub { s!^ba!!; push @resulsts, $_ } ); is_deeply \@resulsts, [ 'foo', 'r', 'z' ]; is_deeply $ret, [ 'foo', 'bar', 'baz' ];
# 微妙にメソッドが足りないのは後で追加する予定。githubにでもいれとくかなぁ。
# 本当はMoose::Autobox::Listのほうに追加したいんだけど、ちとMoose::Autobox::List, Moose::Autobox::Arrayを結構変更しないといけない。