views:

591

answers:

3

I have a list of filenames. I have to create a file for each of those names, write lines to the various files (in no particular order), then close them.

How can I do that in perl? I envision something like the following code (which will not work in that form and give syntax errors):

my @names = qw(foo.txt bar.txt baz.txt);
my @handles;

foreach(@names){
  my $handle;
  open($handle, $_);
  push @handles, $handle; 
}

# according to input etc.:
print $handles[2] "wassup";
print $handles[0] "hello";
print $handles[1] "world";
print $handles[0] "...";

foreach(@handles){
  close $_;
}

How can I do this right?

+1  A: 

Have a look here: How can I create an array of filehandles?

Alan Haggai Alavi
+6  A: 

The filehandle argument of print must be a bareword, a simple scalar, or a block. So:

print { $handles[0] } ...

This is explained in perldoc -f print. The same restriction applies to indirect object syntax in general, as well as for determining when <> is a readline operation, not a glob operation.

ysth
+2  A: 

Here's how I would do it (untested, but I'm pretty sure it is good):

use IO::File;

# ...
my @handles = map { IO::File->new($_, 'w') } @names;

$handles[2]->print("wassup");
# ...

It's OO, it has a cleaner interface, and you don't need to worry about closing them, since it will die when the array goes out of scope.

Todd Gardner
die? perhaps you mean "do so". But the example in the question does that too; nothing to do with IO::File.
ysth
By "die", I meant, the IO::File object would be DESTROYed, which I thought closed the filehandle, but apparently that is just garbage collection, so as long as they are lexically scoped they die anyway.
Todd Gardner