6

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?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Frank
  • 64,140
  • 93
  • 237
  • 324
  • I suspect this would be better done with references to file handles... but I'm not too keen on file handles in perl. – Ape-inago Jun 09 '09 at 03:54

2 Answers2

16

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
  • 96,171
  • 6
  • 121
  • 214
3

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
  • 13,313
  • 39
  • 51
  • die? perhaps you mean "do so". But the example in the question does that too; nothing to do with IO::File. – ysth Jun 09 '09 at 04:09
  • 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 Jun 09 '09 at 04:17
  • "-1" for "you don't need to worry about closing them". You always close whatever you open. – sds Feb 12 '13 at 16:12