throop has asked for the wisdom of the Perl Monks concerning the following question:

Brethern,

I'm trying to bring some old 4.X code up to 5.8. I'm still confused about using strings as filehandles. The tutorial section at File Input and Output says

open(FILE, "data.txt"); #opens data.txt in read-mode while(<FILE>){ #reads line by line from FILE which i +s the filehandle for data.txt chomp; print "Saw $_ in data.txt\n"; #shows you what we have read } close FILE;
Of course, with just a little 'improvement' this loses:
use strict; my($foo) = 'FILE'; open($foo, "data.txt"); #opens data.txt in read-mode while(<$foo>){ #reads line by line from FILE which i +s the filehandle for data.txt chomp; print "Saw $_ in data.txt\n"; #shows you what we have read } close $foo; #close the file.
Gives the dreaded:
Can't use string ("FILE") as a symbol ref while "strict refs" in use at IO.pl line 7.

Oddly, looking through the various tutorials, I can't find a good example of creating a filehandle, binding it to a variable, and passing it around (e.g. as an arg to a subroutine.) What's the ''recomended'' way to do this?

thanks,
throop

Replies are listed 'Best First'.
Re: Still blurry on variables for filehandles
by kyle (Abbot) on Jan 24, 2007 at 16:16 UTC

    You can just open with an undefined scalar and use the scalar the same way you would the filehandle.

    open my $foo, '<', 'data.txt' or die "Can't read data.txt: $!"; while ( <$foo> ) { chomp; #etc. } close $foo;

    The resulting scalar can be passed around to other functions and used there.

Re: Still blurry on variables for filehandles
by bingos (Vicar) on Jan 24, 2007 at 16:24 UTC
Re: Still blurry on variables for filehandles
by Errto (Vicar) on Jan 24, 2007 at 16:34 UTC
    The issue comes from assigning $foo to the string 'FILE'. As others have mentioned, you can call open on an undefined scalar lvalue and it will magically assign a filehandle to it. If you are so inclined, you can also do it explicitly yourself:
    use IO::File; my $foo = new IO::Handle; open $foo, '<', 'data.txt';
    Update: switched modules per ikegami's suggestion.
      I'd use IO::File over FileHandle. FileHandle is a backwards compatibility wrapper for IO::File.