2008年 03月 11日

List::Enumerator

慣れるために書いてみる

package List::Enumerator;

use strict;
use warnings;

use base qw/Exporter/;
our @EXPORT = qw/E/;

use Exception::Class ( "StopEnumeration ");

sub E {
	List::Enumerator->new(@_);
}


sub new {
	my ($class, @args) = @_;

	my $self = {};
	bless $self, $class;

	$self->_init(@args);

	$self;
}

sub _init {
	my ($self, @args) = @_;

	my $i = 0;
	$self->_init_with_fun(sub {
		$i < @args ? $args[$i++] : StopEnumeration->throw;
	});
}

sub _init_with_fun {
	my ($self, $fun) = @_;
	$self->{fun} = $fun;
}

sub next {
	my $self = shift;
	$self->{fun}->();
}

sub each {
	my ($self, $fun) = @_;
	eval {
		while (1) {
			local $_ = $self->next;
			$fun->($_);
		}
	}; if (my $e = Exception::Class->caught('StopEnumeration')) {
	}
}

sub map {
	my ($self, $fun) = @_;
	my @ret = ();
	$self->each(sub {
		push @ret, $fun->($_);
	});
	wantarray ? @ret : List::Enumerator->new(@ret);
}
use Data::Dumper;
sub p { print Dumper shift }

use List::Enumerator;


E(1, 2, 3)->each(sub {
	p shift;
	p $_;
});

p [ E(1, 2, 3)->map(sub { $_ * $_; }) ];

E(1, 2, 3)->map(sub {
	$_ * $_;
})->each(sub {
	p $_;
});

cycle かくまえに眠くなった

もうちょっと経ったら (謎) autobox さわってみよう