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

Okay, I have a routine that says:

open (FILE, "filetoread.something");

but Perl says that according to strict sub (I have use strict; at the top of my code) it says the bareword FILE can't be used, which according to my google searching, means that perl treats every nonvariable/nonfunction as a built in function. so I try shoving it in like this

$filehandle = "FILE"; open ($filehandle, "filetoread.something");

But alas, you can't use references as file handles with "use strict" on. How do I get around this? Can you just not open files inside a sub with "use strict" turned on?

Replies are listed 'Best First'.
Re: 'strict refs' + 'strict sub' = suck.
by hardburn (Abbot) on Oct 24, 2003 at 20:33 UTC

    The code you've posted is perfectly legal (although you really need to check the return value of open: open(FILE, "filetoread") or die "Error opening file: $!\n";). I suspect your error is higher up in the code and perl just happens to error out at that line.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    :(){ :|:&};:

    Note: All code is untested, unless otherwise stated

Re: 'strict refs' + 'strict sub' = suck.
by Plankton (Vicar) on Oct 24, 2003 at 20:41 UTC
    really?
    $ cat test1.pl #!/usr/bin/perl -w use strict; open( FILE, "filetoread.something" ) or die "can't open filetoread.som +ething:$!\n"; while ( <FILE> ) { print; } close(FILE); $ cat filetoread.something blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah $ ./test1.pl blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah $ perl -v This is perl, v5.8.0 built for cygwin-multi-64int

    Plankton: 1% Evil, 99% Hot Gas.
Re: 'strict refs' + 'strict sub' = suck.
by toonski (Beadle) on Oct 24, 2003 at 20:45 UTC
    I dont know what's going on. Keep in mind that this is within a sub, though, the reason strict sub is giving an error. This is the actual code I'm using, it gets a line-delimited list of images from file to keep from wasting sql queries.

    #--GETAVATARS--# sub getavatars { my $id = $_[0]; my $filename = "./avatars/$id/avatar.dat"; open (FILE, "$filename"); my @avatars = <FILE>; close(FILE); return(FILE); }
    and this is the error I get:

    Content-type: text/html ERROR Bareword "FILE" not allowed while "strict subs" in use at ./modules/ad +min/users.cgi line 161. Compilation failed in require at admin.cgi li +ne 54.
      Why would you want to return a closed file handle?

      return(FILE);

      That's the line causing the error. I'm not sure what that subroutine is supposed to do, as it is reading the file into a lexical array, local to the subroutine, and not doing anything with it afterwards. Maybe you want to:

      return @avatars;
      or:
      return \@avatars;

      ?

      Liz

      EDIT: Oh my god, I see the error. I'm not sure why I put "return(FILE), but that's apparently what's causing it. Thanks for your help :)

        Incidentally, if you really meant to return the close handle you would either have used IO::File in the first place or you'd return the glob ala return \*FILE;.

        I guess you need to figure out how to go to specified line numbers in the text editor that you use for perl programming. When perl reports an error at a specific line number, the first thing to try is to go directly to that line number in the file.
Re: 'strict refs' + 'strict sub' = suck.
by runrig (Abbot) on Oct 25, 2003 at 21:16 UTC
    open(FILE, $file) is fine, even with strict subs, but if you're concerned that some other sub in the same package might need simultaneous use of the same filehandle name, then you can do this:
    sub mysub { my $fh = \do { local *FILE}; open($fh, ">myfile")... ... }
    Note that later versions of perl (5.6+ ?) will autovivify a scalar to a file handle so you can just do this:
    sub mysub { open(my $fh, ">myfile")... ... }
Re: 'strict refs' + 'strict sub' = suck.
by Roger (Parson) on Oct 25, 2003 at 12:31 UTC
    Don't use the antique 'open' method, use the IO::File module instead:

    use strict; use IO::File; my $f = new IO::File "filetoread.something", "r" or die "Can not open input file"; while (<$f>) { # do stuff ... } undef $f; # close the file # note that you don't even have to do this # this is optional because the file will be # closed when Perl script finishes. I am just # forcing an early file closure here.

      Why not use open? Why is it "antique"?

      Roger, you've pimped the use of IO::File over open once before in Re: Removing duplicates from list yet you never state why you think IO::File is better. I'm honestly curious as to why you prefer one over the other. Is it just because IO::File uses OO syntax?

      -- vek --
        Since Perl 5.6.0 we can perform file operations using a scalar - which is quite convenient to pass around in function calls. For example -

        open my $fh, ">output.txt" or die "Can't create output: $!"; print {$fh} "Hello world!\n"; close $fh; # if don't close, then it will be closed # automatically when $fh is out of scope.
        However the above code is not valid in version of Perl prior to 5.6.0, which I am still using on some of the production boxes. However the following will work on Perl prior to 5.6.0.
        my $fh = IO::File "output.txt", "w" or die "Can not create output: $!"; print $fh "Hello world!\n"; undef $fh;
        My preference of IO::File over open is on the Perl version compatibility and also ease of use.

        This is only my personal perference however.