tags:

views:

75

answers:

2
use strict;
my @array=('f1','f2','f3');
my $dir ='\tmp';
foreach (@array) {
my $FH = $_;
open ("$FH", ">$dir/${FH}.txt") or die $!;
}

foreach (@array) {
 my $FH = $_;
 close($FH);
}

i got "Can't use string ("f1") as a symbol ref while "strict refs" in use at bbb.pl line 6." error . What is the isuse ?

+5  A: 

You are using a string "f1" as the first argument to open which expects a filehandle.

You probably wanted to do:

my @filehandles = (); # Stash filehandles there so as to not lose filenames
foreach (@array) {
    my $FH = $_;
    open (my $fh, ">", "$dir/${FH}.txt") or die $!;
    push @filehandles, $fh;
}
DVK
+5  A: 

First: 2 arg open is bad, 3 arg open is better.

open( .. , ">", "$dir/${FN}.txt")   

second, what on earth are you doing with open("$FH" ..

argument 1 to open is supposed to be an actual filehandle of sorts which can be connected to a datastream. passing it a string will not work.

INSANE:  open( "Hello world", .... )  # how can we open hello world, its not a file handle
WORKS:   open( *FH,.... )  # but don't do this, globs are package-globals and pesky
BEST:    open( my $fh, .... ) # and they close themself when $fh goes out of scope! 

third

foreach my $filename ( @ARRAY ){ 
}

Forth:

dir = \tmp ? are you sure? I think you meant /tmp , \tmp is something different altogether.

Fifth:

use warnings;

using strict is good, but you should use warnings too.

Sixth: Use names for variables that are explanatory, we know @ is an array @array is not more helpful.

ALL TOGETHER

use strict;
use warnings;

my @filenames=('f1','f2','f3');
my @filehandles = ();
my $dir ='/tmp';
foreach my $filename (@filenames) {
   open (my $fh,'>', "${dir}/${filename}.txt") or die $!;
   push @filehandles, $fh;
}
# some code here, ie: 
foreach my $filehandle ( @filehandles ) { 
   print {$filehandle}  "Hello world!";
}
# and then were done, cleanup time
foreach my $filehandle ( @filehandles ){ 
   close $filehandle or warn "Closing a filehandle didn't work, $!";
}

Alternatively, depending on what you were trying to do, this may have been better code:

use strict;
use warnings;

my @filenames=('f1','f2','f3');
my $dir ='/tmp';
foreach my $filename (@filenames) {
   open (my $fh,'>', "${dir}/${filename}.txt") or die $!;
   print {$fh}  "Hello world!";
}

I don't explicitly close $fh, because its not needed, as soon as $fh goes out of scope ( at the end of the block in this case ) it is closed automatically.

Kent Fredric
1-arg open is best. or shortest or something like that.
ysth
Damn you ysth, damn you. I went and researched how 1-arg open works, and now myself, and a small group of people on IRC, wish they didn't know. ` perl -e '$FILE = q{ps aux |}; open(FILE) or die $!; print <FILE>;'` *YUCK*
Kent Fredric
@ysth: we should campaign for 0-arg open. `perl -we 'for (q{ps aux |}){ open _; print <_>; }'` is too long. `for (q{ps aux |}){ open; print <_>; } ` or even `open `
Kent Fredric