Range Over Iterators in Perl

Starting with version 1.23, the specified language has added support for iterators, which lets us range over pretty much anything!

Let’s look at the List type again. In that example, we had an AllElements method that rendered a list of all elements. With iterators, we can do it better - as shown below.

# Define List and element types using Perl objects
package List;
use strict;
use warnings;

sub new {
    my ($class) = @_;
    return bless { head => undef, tail => undef }, $class;
}

sub push {
    my ($self, $val) = @_;
    my $new_element = { val => $val, next => undef };
    if (!$self->{tail}) {
        $self->{head} = $self->{tail} = $new_element;
    } else {
        $self->{tail}->{next} = $new_element;
        $self->{tail} = $new_element;
    }
}

sub all {
    my ($self) = @_;
    return sub {
        my $yield = shift;
        for (my $e = $self->{head}; $e; $e = $e->{next}) {
            return 0 unless $yield->($e->{val});
        }
        return 1;
    };
}

package main;

use strict;
use warnings;
use List::Util qw(reduce);

sub gen_fib {
    return sub {
        my $yield = shift;
        my ($a, $b) = (1, 1);
        while (1) {
            return 0 unless $yield->($a);
            ($a, $b) = ($b, $a + $b);
        }
    };
}

# Create List and add elements
my $lst = List->new;
$lst->push(10);
$lst->push(13);
$lst->push(23);

# Use the iterator in a loop
my $iterator = $lst->all;
$iterator->(sub {
    print "$_[0]\n";
    return 1;
});

# Collect all items into an array
my @all = ();
$iterator->(sub {
    push @all, $_[0];
    return 1;
});
print "all: [", join(" ", @all), "]\n";

# Iterate through Fibonacci numbers
my $fib_iterator = gen_fib;
$fib_iterator->(sub {
    my $n = shift;
    return 0 if $n >= 10;
    print "$n\n";
    return 1;
});

To run this Perl script, save the code to a file and execute it using Perl.

$ perl script.pl

Outputs:

10
13
23
all: [10 13 23]
1
1
2
3
5
8

Now that we can run and use basic iterators in Perl, let’s learn more about the language.