Skip to content

Commit

Permalink
implement streaming helpers to for/map/grep/reduce items in an io object
Browse files Browse the repository at this point in the history
  • Loading branch information
wchristian committed Dec 10, 2014
1 parent 4d1cfd1 commit 9dc1955
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
49 changes: 49 additions & 0 deletions lib/IO/All.pm
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,55 @@ sub getlines {
return ();
}

sub stream_meth {}

sub for {
my ( $self, $code ) = @_;
my $stream_meth = $self->stream_meth;
die "Streaming helpers not supported for ".ref($self) if !$stream_meth;
while ( defined( my $item = $self->$stream_meth ) ) {
$_ = $item;
$code->( $item );
}
return;
}

sub map {
my ( $self, $code ) = @_;
my $stream_meth = $self->stream_meth;
die "Streaming helpers not supported for ".ref($self) if !$stream_meth;
my @lines;
while ( defined( my $item = $self->$stream_meth ) ) {
$_ = $item;
push @lines, $code->( $item );
}
return @lines;
}

sub grep {
my ( $self, $code ) = @_;
my $stream_meth = $self->stream_meth;
die "Streaming helpers not supported for ".ref($self) if !$stream_meth;
my @lines;
while ( defined( my $item = $self->$stream_meth ) ) {
$_ = $item;
next if !$code->( $item );
push @lines, $item;
}
return @lines;
}

sub reduce {
my ( $self, $code, $accum ) = @_;
my $stream_meth = $self->stream_meth;
die "Streaming helpers not supported for ".ref($self) if !$stream_meth;
while ( defined( my $item = $self->$stream_meth ) ) {
$_ = $item;
$accum = $code->( $accum, $item );
}
return $accum;
}

sub is_dir {my $self = shift; UNIVERSAL::isa($self, 'IO::All::Dir') }
sub is_dbm {my $self = shift; UNIVERSAL::isa($self, 'IO::All::DBM') }
sub is_file {my $self = shift; UNIVERSAL::isa($self, 'IO::All::File') }
Expand Down
2 changes: 2 additions & 0 deletions lib/IO/All/Dir.pm
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ sub rmtree {
File::Path::rmtree($self->pathname, @_);
}

sub stream_meth { "next" }

sub glob {
my ($self, @rest) = @_;

Expand Down
2 changes: 2 additions & 0 deletions lib/IO/All/File.pm
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ sub head {
return wantarray ? @return : join '', @return;
}

sub stream_meth { "getline" }

sub tail {
my $self = shift;
my $lines = shift || 10;
Expand Down
28 changes: 28 additions & 0 deletions test/stream_helpers.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use strict;
use warnings;
use Test::More;
use IO::All -binary;

my $t = -e 't' ? 't' : 'test';
my $io = io( "$t/mystuff" );

my %hash;
my @for = $io->for( sub { $hash{$_} = length } );
is_deeply \%hash, { "No bluff.\n" => 10, "is quite enough.\n" => 17, "My stuff\n" => 9 },
"for runs a bit of code on each line";
is_deeply \@for, [], "for returns nothing";

my @map = $io->map( sub { "$_+", "-" } );
is_deeply \@map, [ "My stuff\n+", "-", "is quite enough.\n+", "-", "No bluff.\n+", "-" ],
"map returns modified version of the input lines";

my @grep = $io->grep( sub { /uff/ } );
is_deeply \@grep, [ "My stuff\n", "No bluff.\n" ], "grep finds the lines for which \$code is true";

my $reduce = $io->reduce( sub { shift() + length }, 0 );
is $reduce, 36, "reduce returns an accumulator based on the input lines";

my $grep_dir = io->dir($t)->grep( sub { !/\./ } );
is $grep_dir, 9, "grep works on directories too";

done_testing;

0 comments on commit 9dc1955

Please sign in to comment.