Subject: | add getline method to iterators |
I'd really like to be able to pass iterators back to a PSGI server.
wrapping up a DBIC resultset in an ifilter would be a great way to
stream data.
PSGI relies on the getline method to stream data, which has the same
effect as the diamond operator ('<>'). This patch adds the getline
method to further duck type the file handle interface.
Subject: | 0001-add-getline-method-to-iterators-to-emulate-file-hand.patch |
From 2369a8a4bcfd8446ee138c7405a768b0550553dd Mon Sep 17 00:00:00 2001
From: Paul C. Mantz <pcmantz@gmail.com>
Date: Tue, 22 Nov 2011 12:42:08 -0600
Subject: [PATCH] add getline method to iterators to emulate file handles better
---
lib/Iterator/Simple.pm | 24 +++++++++++++++---------
t/10_basic.t | 20 +++++++++++---------
t/12_list.t | 16 +++++++++++++++-
3 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/lib/Iterator/Simple.pm b/lib/Iterator/Simple.pm
index add6406..a07081d 100644
--- a/lib/Iterator/Simple.pm
+++ b/lib/Iterator/Simple.pm
@@ -43,9 +43,11 @@ sub iter {
if($method = $self->can('__iter__')) {
return $method->($self);
}
- if($method = overload::Method($self, '<>') || $self->can('next')) {
- return ITERATOR_CLASS->new(sub { $method->($self) });
- }
+ if ( $method = overload::Method($self, '<>')
+ || $self->can('next')
+ || $self->can('getline')) {
+ return ITERATOR_CLASS->new(sub { $method->($self) });
+ }
if($method = overload::Method($self, '&{}')) {
return ITERATOR_CLASS->new($method->($self));
}
@@ -79,6 +81,7 @@ sub is_iterable {
$self->isa(ITERATOR_CLASS)
or $self->can('__iter__')
or $self->can('next')
+ or $self->can('getline')
or overload::Method($self, '<>')
or overload::Method($self, '&{}')
or overload::Method($self,'@{}')
@@ -132,8 +135,10 @@ sub list {
push @list, $val while defined($val = $iter->());
return \@list;
}
- if($method = overload::Method($self, '<>') || $self->can('next')) {
- my(@list, $val);
+ if ( $method = overload::Method($self, '<>')
+ || $self->can('next')
+ || $self->can('getline')) {
+ my (@list, $val);
push @list, $val while defined($val = $method->($self));
return \@list;
}
@@ -366,8 +371,8 @@ sub iarray {
use Carp;
use overload (
- '<>' => 'next',
- '|' => 'filter',
+ '<>' => 'getline',
+ '|' => 'filter',
fallback => 1,
);
@@ -378,7 +383,8 @@ sub iarray {
bless $_[1], $_[0];
}
- sub next { goto shift }
+ sub next { goto shift }
+ *getline = \&next;
sub __iter__ { $_[0] }
@@ -387,7 +393,7 @@ sub iarray {
*chain = \&Iterator::Simple::ichain;
*zip = \&Iterator::Simple::izip;
*enumerate = \&Iterator::Simple::ienumerate;
- *slice = \&Iterator::Simple::islice;
+ *slice = \&Iterator::Simple::islice;
sub head { Iterator::Simple::ihead($_[1], $_[0]); }
sub skip { Iterator::Simple::iskip($_[1], $_[0]); }
}
diff --git a/t/10_basic.t b/t/10_basic.t
index 455ba0d..a7f7306 100644
--- a/t/10_basic.t
+++ b/t/10_basic.t
@@ -1,4 +1,4 @@
-use Test::More tests => 5;
+use Test::More tests => 6;
use strict;
use warnings;
@@ -46,6 +46,16 @@ ok( mk_itr(1,5), 'iterator creation' );
#5
{
+ $itr = mk_itr(0,4);
+ my @res;
+ while(defined(my $r = $itr->getline)) {
+ push @res, $r;
+ }
+ is_deeply ( \@res, [0,1,2,3,4], 'getline' );
+}
+
+#6
+{
$itr = mk_itr(1,5);
my @res;
while(<$itr>) {
@@ -53,11 +63,3 @@ ok( mk_itr(1,5), 'iterator creation' );
}
is_deeply ( \@res, [1,2,3,4,5], '"<>" overload' );
}
-
-# @{} overloads could cause confusion
-##6
-#{
-# $itr = mk_itr(12,17);
-# is_deeply ( [@{$itr}], [12,13,14,15,16,17], '"@{}" overload' );
-#}
-
diff --git a/t/12_list.t b/t/12_list.t
index 796fb60..dc5e1e1 100644
--- a/t/12_list.t
+++ b/t/12_list.t
@@ -1,4 +1,4 @@
-use Test::More tests => 8;
+use Test::More tests => 9;
use strict;
use warnings;
@@ -44,6 +44,11 @@ use Iterator::Simple qw(list iterator);
}
{
+ my $buz = Buz->new();
+ is_deeply list($buz) , [0,1,2,3,4,5,6,7,8,9,10,11], 'list(getline implemented)';
+}
+
+{
is_deeply list(), [], 'list()';
}
@@ -91,6 +96,15 @@ use Iterator::Simple qw(list iterator);
}
}
+{
+ package Buz;
+ sub new { bless {i => 0}, $_[0]; }
+ sub getline {
+ my($self) = @_;
+ return if $self->{i} > 11;
+ return $self->{i}++;
+ }
+}
__END__
foo
--
1.7.4.1