in reply to list reversal closure

I find examples like the following more useful:
sub reverse_iterator { my @list = @_; my $i = $#list; sub { return if $i < 0; return $list[$i--]; }; } my $foo = reverse_iterator(@ARGV); while (defined ($_ = $foo->())) { print; }

Replies are listed 'Best First'.
Re^2: list reversal closure
by ikegami (Patriarch) on Aug 21, 2006 at 16:48 UTC

    Since the loop stop when undefined is returned, the following is the same, but simpler:

    sub reverse_iterator { my @list = @_; sub { return pop @list; }; }

    Update: I prefer to signal the end of the list out of band to allow undefined values in @list. That why I prefer returning the value through an argument.

    sub reverse_iterator { my @list = @_; sub { return unless @list; $_[0] = pop @list; return 1; }; } my $foo = reverse_iterator(@ARGV); while ($foo->(my $val)) { print("$val\n"); }

    Update: I just noticed that you assigned to $_ without localizing it first. Don't do that!

    Update: s/shift/pop/

      So how about this as an alternative?:

      #!/usr/bin/perl -l sub revlist { my @list = @_; sub { pop @list }; } my $foo = revlist(@ARGV); print while local $_ = $foo->();

      Edit: Optionally, closure subroutine might look like this, of course:

      sub { return unless @list; pop @list; };

      print substr("Just another Perl hacker", 0, -2);
      - apotheon
      CopyWrite Chad Perrin

Re^2: list reversal closure
by ysth (Canon) on Aug 22, 2006 at 18:46 UTC
    Using your iterator, but with a slightly different invocation:
    my $foo = reverse_iterator("a",undef,"c"); while (my ($elem) = $foo->()) { print( defined( $elem ) ? $elem : "undef" ); }