what about the following code:
open(FOO,'<foo.txt');
@LIST=['FOO','.bashrc'];
while (<@LIST>) {
process;
}
and a directory containing the files FOO, foo.txt, and .bashrc
Does <@LIST> treat FOO as a filehandle or a filename? Or maybe this
would be clearer...
open(LOG,'>/tmp/output.log');
opendir(FOO,'.');
@dir=readdir FOO;
while (<@dir> ) {
process;
}
and a directory having files 'FOO','STDOUT','STDIN' and 'LOG'. Do we
treat as filehandles or files?
I agree, it's streching for an example, but I hope the question is
clear?
Monty
Perl6 RFC Librarian wrote:
>
> This and other RFCs are available on the web at
> http://dev.perl.org/rfc/
>
> =head1 TITLE
>
> Angle brackets should accept filenames and lists
>
> =head1 VERSION
>
> Maintainer: Jon Ericson <[EMAIL PROTECTED]>
> Date: 6 August 2000
> Version: 1
> Mailing List: [EMAIL PROTECTED]
> Number: 51
>
> =head1 ABSTRACT
>
> If the file-globbing behavior of angle brackets is
> removed (RFC 34), enclosing a non-filehandle will be
> undefined. Perl should treat non-filehandles as
> filenames and Do What I Mean. Also, angle brackets
> should should handle lists (of filenames and
> filehandles).
>
> =head1 DESCRIPTION
>
> =head2 Background
>
> >From perlop/"I/O Operators":
>
> In scalar context, evaluating a filehandle in angle brackets yields
> the next line from that file (the newline, if any, included), or
> C<undef> at end-of-file or on error. When C<$/> is set to C<undef>
> (sometimes known as file-slurp mode) and the file is empty, it
> returns C<''> the first time, followed by C<undef> subsequently.
>
> [snipped use of angle brackets in a while loop and predefined filehandles]
>
> If a <FILEHANDLE> is used in a context that is looking for
> a list, a list comprising all input lines is returned, one line per
> list element. It's easy to grow to a rather large data space this
> way, so use with care.
>
> <FILEHANDLE> may also be spelled C<readline(*FILEHANDLE)>.
> See L<perlfunc/readline>.
>
> The null filehandle <> is special: it can be used to emulate the
> behavior of B<sed> and B<awk>. Input from <> comes either from
> standard input, or from each file listed on the command line. Here's
> how it works: the first time <> is evaluated, the @ARGV array is
> checked, and if it is empty, C<$ARGV[0]> is set to "-", which when opened
> gives you standard input. The @ARGV array is then processed as a list
> of filenames. The loop
>
> while (<>) {
> ... # code for each line
> }
>
> is equivalent to the following Perl-like pseudo code:
>
> unshift(@ARGV, '-') unless @ARGV;
> while ($ARGV = shift) {
> open(ARGV, $ARGV);
> while (<ARGV>) {
> ... # code for each line
> }
> }
>
> except that it isn't so cumbersome to say, and will actually work.
> It really does shift the @ARGV array and put the current filename
> into the $ARGV variable. It also uses filehandle I<ARGV>
> internally--<> is just a synonym for <ARGV>, which
> is magical. (The pseudo code above doesn't work because it treats
> <ARGV> as non-magical.)
>
> You can modify @ARGV before the first <> as long as the array ends up
> containing the list of filenames you really want. Line numbers (C<$.>)
> continue as though the input were one big happy file. See the example
> in L<perlfunc/eof> for how to reset line numbers on each file.
>
> If you want to set @ARGV to your own list of files, go right ahead.
> This sets @ARGV to all plain text files if no @ARGV was given:
>
> @ARGV = grep { -f && -T } glob('*') unless @ARGV;
>
> You can even set them to pipe commands. For example, this automatically
> filters compressed arguments through B<gzip>:
>
> @ARGV = map { /\.(gz|Z)$/ ? "gzip -dc < $_ |" : $_
> } @ARGV;
>
> If you want to pass switches into your script, you can use one of the
> Getopts modules or put a loop on the front like this:
>
> while ($_ = $ARGV[0], /^-/) {
> shift;
> last if /^--$/;
> if (/^-D(.*)/) { $debug = $1 }
> if (/^-v/) { $verbose++ }
> # ... # other switches
> }
>
> while (<>) {
> # ... # code for each line
> }
>
> The <> symbol will return C<undef> for end-of-file only once.
> If you call it again after this, it will assume you are processing another
> @ARGV list, and if you haven't set @ARGV, will read input from STDIN.
>
> =head2 Easy things should be easy
>
> Input from a file is already easy in Perl, but it
> could be easier.
>
> =head2 Flexibility
>
> As noted above, the behavior this RFC proposes is
> already partially availible with @ARGV and <>. But
> you can't mix filenames with filehandles. Nor is it
> obvious what you are doing. And it takes two steps.
>
> =head1 IMPLEMENTATION
>
> Let:
>
> while (<LIST>) {
> # code for each line
> }
>
> be "equivalent to the following Perl-like pseudo code":
>
> @ARGV = LIST;
> unshift(@ARGV, '-') unless @ARGV;
> while ($ARGV = shift) {
> my $fh;
> if (ref $ARGV eq 'GLOB'){ # or filehandle ref result
> $fh = $ARGV;
> }else{ # should we include other cases (e.g. array refs)?
> open($fh, $ARGV) or warn "can't open $ARGV: $!";
> };
> while (<$fh>) {
> # code for each line
> };
> };
>
> =head1 REFERENCES
>
> RFC 34 - Angle brackets should not be used for file globbing.
> perlop/"I/O Operators"