use IO::Dir; sub make_reader2 { my ($dirname) = @_; my $d = new IO::Dir $dirname or die "opendir $dirname: $!"; my $next; return sub { while (1) { unless (defined $next) { my $entry = $d->read or return; next if $entry eq '.'; next if $entry eq '..'; $entry = "$dirname/$entry"; if (-d $entry) { $next = make_reader2($entry); } else { $next = sub { my $r = $entry; undef $entry; $r; }; } } my $result = $next->(); return $result if defined $result; undef $next; } }; } my $reader = make_reader2($ARGV[0]); print "$_\n" while (defined($_ = $reader->()));