factor out ArrayStream, update new stream types to respect peek
Matt S Trout [Fri, 28 May 2010 19:03:18 +0000 (20:03 +0100)]
lib/HTML/Zoom/ArrayStream.pm [new file with mode: 0644]
lib/HTML/Zoom/CodeStream.pm
lib/HTML/Zoom/FilterStream.pm
lib/HTML/Zoom/FlattenedStream.pm
lib/HTML/Zoom/MappedStream.pm
lib/HTML/Zoom/StreamBase.pm
lib/HTML/Zoom/StreamUtils.pm
t/actions.t

diff --git a/lib/HTML/Zoom/ArrayStream.pm b/lib/HTML/Zoom/ArrayStream.pm
new file mode 100644 (file)
index 0000000..7a7e05c
--- /dev/null
@@ -0,0 +1,21 @@
+package HTML::Zoom::ArrayStream;
+
+use strict;
+use warnings FATAL => 'all';
+use base qw(HTML::Zoom::StreamBase);
+
+sub new {
+  my ($class, $args) = @_;
+  bless(
+    { _zconfig => $args->{zconfig}, _array => [ @{$args->{array}} ] },
+    $class
+  );
+}
+
+sub _next {
+  my $ary = $_[0]->{_array};
+  return unless @$ary;
+  return shift @$ary;
+}
+
+1;
index 1d70a58..0755a3b 100644 (file)
@@ -4,29 +4,13 @@ use strict;
 use warnings FATAL => 'all';
 use base qw(HTML::Zoom::StreamBase);
 
-sub from_array {
-  my ($class, @array) = @_;
-  $class->new({ code => sub {
-    return unless @array;
-    return shift @array;
-  }});
-}
-
 sub new {
   my ($class, $args) = @_;
   bless({ _code => $args->{code}, _zconfig => $args->{zconfig} }, $class);
 }
 
-sub next {
-  my ($self) = @_;
-
-  # peeked entry so return that
-
-  if (exists $self->{_peeked}) {
-    return (delete $self->{_peeked});
-  }
-
-  $self->{_code}->();
+sub _next {
+  $_[0]->{_code}->();
 }
 
 1;
index e6d7a83..a0bc6b7 100644 (file)
@@ -17,15 +17,9 @@ sub new {
   );
 }
 
-sub next {
+sub _next {
   my ($self) = @_;
 
-  # peeked entry so return that
-
-  if (exists $self->{_peeked}) {
-    return (delete $self->{_peeked});
-  }
-
   # if our main stream is already gone then we can short-circuit
   # straight out - there's no way for an alternate stream to be there
 
index 28c44c2..d33c9ea 100644 (file)
@@ -9,7 +9,8 @@ sub new {
   bless({ _source => $args->{source}, _zconfig => $args->{zconfig} }, $class);
 }
 
-sub next {
+sub _next {
+
   return unless (my $self = shift)->{_source};
   my ($next, $s);
   until (($next) = ($s = $self->{_cur}) ? $s->next : ()) {
index 09ef6be..7d0c505 100644 (file)
@@ -12,7 +12,7 @@ sub new {
   }, $class);
 }
 
-sub next {
+sub _next {
   return unless (my $self = shift)->{_source};
   # If we were aiming for a "true" perl-like map then we should
   # elegantly handle the case where the map function returns 0 events
index c04c7b6..a733656 100644 (file)
@@ -11,12 +11,25 @@ sub peek {
   if (exists $self->{_peeked}) {
     return ($self->{_peeked});
   }
-  if (my ($peeked) = $self->next) {
+  if (my ($peeked) = $self->_next) {
     return ($self->{_peeked} = $peeked);
   }
   return;
 }
 
+sub next {
+  my ($self) = @_;
+
+  # peeked entry so return that
+
+  if (exists $self->{_peeked}) {
+    return (delete $self->{_peeked});
+  }
+
+  $self->_next;
+}
+
+
 sub flatten {
   my $self = shift;
   require HTML::Zoom::FlattenedStream;
index c30500c..3b2f921 100644 (file)
@@ -8,6 +8,7 @@ use Scalar::Util ();
 
 use HTML::Zoom::CodeStream;
 use HTML::Zoom::FilterStream;
+use HTML::Zoom::ArrayStream;
 
 sub stream_from_code {
   my ($self, $code) = @_;
@@ -20,10 +21,10 @@ sub stream_from_code {
 sub stream_from_array {
   my $self = shift;
   my @array = @_;
-  $self->stream_from_code(sub {
-    return unless @array;
-    return shift @array;
-  });
+  HTML::Zoom::ArrayStream->new({
+    array => \@array,
+    zconfig => $self->_zconfig,
+  })
 }
 
 sub stream_concat {
index 5e9bf16..1d83aa1 100644 (file)
@@ -268,12 +268,12 @@ is(
     $_->repeat_content(
       [
         sub {
-          HTML::Zoom::CodeStream->from_array(
+          HTML::Zoom::ArrayStream->new({ array => [
             (filter
               filter($_ => '.name' => $r_content->('mst'))
               => '.career' => $r_content->('Chainsaw Wielder')),
-            HTML::Zoom::CodeStream->from_array(@between)
-          )->flatten
+            HTML::Zoom::ArrayStream->new({ array => \@between })
+          ] })->flatten
         },
         sub {
           filter