in reply to Llama ./tac stumper

You're pretty close:
use strict; use warnings; my @lines; foreach my $file ( reverse @ARGV ) { open my $fh, '<', $file or die "Bleah: $!"; my( @slurp ) = <$fh>; push @lines, reverse @slurp; close $fh; } print foreach @lines;

This could be done with a lot more memory efficiency (without slurping the files) if you take steps to read the file in backwards in the first place (using File::ReadBackwards or Tie::File). But I kept it to stuff that you would probably find explained in the Llama book.

You usually automagically open the contents of @ARGV with the bare <> operator. Since I wanted to treat the files in reverse order, I didn't use <>'s magic, and instead opened the files explicitly. Actually that step could have been avoided if I had reversed the contents of @ARGV first, and then still relied upon <> to do its magic.

UPDATE: I wanted to go ahead and show how it is simplified by letting <> do its magic. Here goes:

use strict; use warnings; my @lines; @ARGV = reverse @ARGV; foreach ( @ARGV ) { my( @slurp ) = <>; push @lines, reverse @slurp; } print foreach @lines;

Enjoy!


Dave

Replies are listed 'Best First'.
Re^2: Llama ./tac stumper
by BUU (Prior) on Jun 07, 2004 at 05:21 UTC
    Unless I'm badly confused, I'm pretty sure that foreach( @ARGV ){ <> } isn't doing what you want. <> in list context should open every file in @ARGV, read all the lines, and return them.
    @ARGV=reverse @ARGV; print reverse <>;
      My apologies on botching the 2nd solution. Here's an update:

      use strict; use warnings; my( @slurp ) = <>; @slurp = reverse @slurp; print @slurp;

      Dave

        You did actually verify if I was right didn't you?