Skip to content

Instantly share code, notes, and snippets.

@hoehrmann
Last active December 14, 2015 18:48
Show Gist options
  • Save hoehrmann/5131504 to your computer and use it in GitHub Desktop.
Save hoehrmann/5131504 to your computer and use it in GitHub Desktop.
Acme::IEnumerable, lazy generators for Perl.
package main;
use Modern::Perl;
use Coro::Generator;
my $even = generator {
my $x = 0;
while(1) {
$x += 2;
# use references as boxing mechanism
# yield non-reference to indicate end
yield \$x;
}
};
my $enum = Acme::IEnumerable->from($even);
# prints 2 4 6
say for $even->where(sub { $_ > 5 })
->take(3)
->to_list;
package Acme::IEnumerable;
use strict;
use warnings;
use Coro::Generator;
sub to_list {
my ($enum) = @_;
my @list;
while (1) {
my $item = $enum->();
last unless ref $item;
push @list, $$item;
}
@list;
}
sub take {
my ($enum, $count) = @_;
my $self = generator {
for (0 .. $count - 1) {
my $item = $enum->();
yield $item;
}
yield undef while 1;
};
bless $self, ref $enum;
}
sub where {
my ($enum, $filter) = @_;
my $self = generator {
while (1) {
my $item = $enum->();
local $_ = $item;
next unless $filter->($item);
yield $item;
}
};
bless $self, ref $enum;
}
sub from {
my $class = shift;
my $from = shift;
bless $from, $class;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment