Larry wrote: > So you can do it any of these ways: > > for <$dance> { > > for $dance.each { > > for each $dance: { > ^ note colon > > Then there's this approach to auto-iteration: > > my @dance := Iterator.new(@squares); > for @dance { Okay, so now I need to make sense of the semantics of <...> and C<for> and coroutines and their combined use. Is the following correct? ============================================================================== The presence of a C<yield> automatically makes a subroutine a coroutine: sub fibs { my ($a, $b) = (0, 1); loop { yield $b; ($a, $b) = ($b, $a+$b); } } Calling such a coroutine returns an Iterator object with (at least) the following methods: next() # resumes coroutine body until next C<yield> next(PARAM_LIST) # resumes coroutine body until next C<yield>, # rebinding params to the args passed to C<next>. # PARAM_LIST is the same as the parameter list # of the coroutine that created the Iterator each() # returns a lazy array, each element of which # is computed on demand by the appropriate # number of resumptions of the coroutine body In a scalar context: <$fh> # Calls $fh.readline (or maybe that's $fh.next???> <$iter> # Calls $iter.next fibs() # Returns iterator object <fibs()> # Returns iterator object and calls that # object's C<next> method (see note below) In a list context: <$fh> # Calls $fh.each <$iter> # Calls $iter.each fibs() # Returns iterator object <fibs()> # Returns iterator object and calls object's C<each> So then: for <$fh> {...} # Build and then iterate a lazy array (the elements # of which call back to the filehandle's input # retrieval coroutine) for <$iter> {...} # Build and then iterate a lazy array (the elements # of which call back to the iterator's coroutine) for fibs() {...} # Loop once, setting $_ to the iterator object # that was returned by C<fibs> for <fibs()> {...} # Build and then iterate a lazy array (the elements # of which call back to the coroutine of the # iterator returned by C<fibs> ============================================================================== Note: this all hangs together *very* nicely, except when someone writes: loop { my $nextfib = <fibs()>; ... } In which case $nextfib is perennially 1, since every call to C<fibs> returns a new Iterator object. The solution is very simple, of course: my $nextfib = <my $iter//=fibs()>; but we might want to contemplate issuing a warning when someone calls an argumentless coroutine within a scalar context <...>. DamianThread Previous | Thread Next