tags:

views:

729

answers:

8

Adding a standard Perl file open function to each script I have is a bit annoying:

sub openfile{
    (my $filename) = @_;
    open FILE,"$filename" or die $!;
    my @lines = <FILE>;
    return @lines;
}

and I can create a Perl module to do this, but this is so simple I'm sure there should be one out there already.

I'm trying to find a way to read a text file into an array, and I cant seem to find a Perl module out there that can do this simple task... maybe I'm looking too hard and it already came with the standard 5.10 install.

Optimally I believe it would look something like this:

my @lines = Module::File::Read("c:\some\folder\structure\file.txt");
+11  A: 

that is the famous "slurp mode":

  my @lines = <FILEHANDLE> ;

you may also see Perl Slurp Ease

dfa
"slurp mode" is more commonly used to mean reading the whole file into a single scalar, by setting the record separator $/ to undef.
ysth
+14  A: 

I think this is what you are looking for

File::Slurp

neomorphic
+4  A: 

You've gotten the general techniques, but I want to put in that Perl sort of discourages you from doing that because it's very often the case that you can do the same thing you're doing one-line-at-a-time, which is inherently far more efficient.

chaos
A good point, especially when reading into an array. Arrays imply sequential processing by lines (or records if $/ is being used) which is often better done one-item-at-a-time. However, there are cases where it is appropriate to slurp.
Chas. Owens
+6  A: 

You might also want to consider using Tie::File, particularly if you are reading larger files and don't want to read the entire file into memory. It's a core module. Also, please refer to perlfaq5.

Joe Suarez
+2  A: 

For quick and dirty, I rather like the simplicity of mucking with @ARGV.

# Ysth is right, it doesn't automatically die; I need another line.
use 5.010;
use strict;
my @rows = do { 
    use warnings FATAL => 'inplace'; # oddly enough, this is the one. ??
    @ARGV='/a/file/somewhere';
    <>;
};
say q(Not gettin' here.);

If perl* cannot open the file, it automatically dies.


* - the executable, so please don't capitalize.

Axeman
I didn't know that Perl wasn't an abbreviation! Thanks for the heads up.
Brian
Sorry, the note was not for you but for the notorious Capital-P gang. They'll break into your post and capitalize your P's when you specifically meant the executable. The language gets a capital-P--only. There's no anagram, though.
Axeman
re.pl # its perl, but its a read-eval-parse-loop :)
Kent Fredric
read-eval-print-loop*
Kent Fredric
http://search.cpan.org/dist/Devel-REPL/
Kent Fredric
I thought the capital-P gang was careful to distinguish.
ysth
No, perl does *not* automatically die - it just warns and continues.
ysth
+4  A: 

Also have a look at Perl6::Slurp which implements the Perl6 version of slurp and is recommended in the "Perl Best Practices" book.

Some examples....

my @lines         = slurp 'filename';
my @lines_chomped = slurp 'filename', { chomp => 1 };
my @lines_utf8    = slurp 'filename', { utf8  => 1 };

/I3az/

draegtun
+9  A: 

You have several options, the classic do method:

my @array = do {
    open my $fh, "<", $filename
        or die "could not open $filename: $!";
    <$fh>;
};

The IO::All method:

use IO::All;

my @array = io($filename)->slurp;

The File::Slurp method:

use File::Slurp;

my @array = read_file($filename);

And probably many more, after all TIMTOWTDI.

Chas. Owens
Definately like the File::Slurp method. Thank you so much!
Brian
A: 

I would recommend an object oriented approach that does not requires Modules outside the CORE distribution and will work anywhere: use strict; use warnings; use IO::File; my $fh = IO::File->new("< $file");

foreach($fh->getlines){ do_something($_); } $fh->close

Berov