package Iterator; sub TIESCALAR { bless $_[1], $_[0] } sub STORE {} sub FETCH { $_[0]->[1] = 0 if ! $_[0]->[1] || $_[0]->[1] == @{ $_[0]->[2] }; $_[0]->[1]++ } package Coroutine; sub new { my $self = bless [[[]]], $_[0]; tie $self->[0][0], 'Iterator', $self->[0]; return $self; } sub add_section { push @{ $_[0]->[0][2] } , $_[1] } sub create { my $s = shift; return sub { $s->[0][2][ $s->[0][0] ]->($s, @_) } } 42; #### #!/usr/bin/perl use strict; use warnings; use Coroutine; my $coroutine = Coroutine->new(); $coroutine->add_section( sub { my $self = shift; $self->[3] = shift; $self->[4] = \@_; print "$_\n" for @{ $self->[4] }; return $self->[3]++; } ); $coroutine->add_section( sub { my $self = shift; print "$self->[3]\n"; return rand() > .5 ? 'weird' : ++$self->[3]; } ); $coroutine->add_section( sub { my $self = shift; print "The end is near - goodbye cruel "; return pop @{ $self->[4] }; } ); my $wacky = $coroutine->create(42, 'hello', 'world'); print $wacky->(42, 'hello', 'world'), "\n"; print $wacky->(), "\n"; print $wacky->(), "\n"; print $wacky->(), "\n"; #### coroutine create { my $foo = shift; my @bar = @_; print "$_\n" for @bar; yield $foo++; print "$foo\n"; yield rand() > .5 ? 'weird' : ++$foo; print "The end is near - goodbye cruel "; yield pop @bar; } my $wacky = create(42, 'hello', 'world'); print $wacky->(42, 'hello', 'world'), "\n"; print $wacky->(), "\n"; print $wacky->(), "\n"; print $wacky->(), "\n"; __END__ hello world 42 43 44|weird The end is near - goodbye cruel world 0