[% setvar title Angle brackets should accept filenames and lists %]

This file is part of the Perl 6 Archive

Note: these documents may be out of date. Do not use as reference!

To see what is currently happening visit http://www.perl6.org/

TITLE

Angle brackets should accept filenames and lists

VERSION

  Maintainer: Jon Ericson <Jonathan.L.Ericson@jpl.nasa.gov>
  Date: 8 Aug 2000
  Mailing List: perl6-language-io@perl.org
  Number: 51
  Version: 2
  Status: Developing

ABSTRACT

The input operator should Do What I Mean. If I pass it a filename, it should try to open that file and readline it. If I pass it a dirname, it should open that directory and readdir it. If I pass it a list of scalars, it should try to open and read from them.

DESCRIPTION

Background

Currently there are two modes of operation for <>. The glob mode should go away (RFC 34). The input operator mode also has two modes: readline from a filehandle and readline from a list of file names (the empty filehandle). Both modes are useful.

Currently directories have seperate handles and functions.

Easy things should be easy

Input from a file is already easy in Perl, but it could be easier. Input from a directory is a pain in the neck.

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. Don't even think about using directory names.

High Level Language

The average Perl programmer should never have to open a file or directory explicitly. Error checking on opens is a pain and repetative. @ARGV and <> is confusing to almost everybody. Wouldn't it be nice to write:

  while (<grep(-f, <~>)>){ # list of plain files in my home dir
     # do something with each line
  };
  print <map { /\.(gz|Z)$/ ? "gzip -dc < $_ |" : $_ } </src>>;

as opposed to:

  opendir my $dir, '~' or die "can't open ~: $!";
  my @file = grep(-f, readdir $dir);
  @ARGV = @file;
  while(<>){
     # do something with each line
  };
  opendir my $other_dir, '/src' or die "can't open /src: $!";
  @ARGV = map { /\.(gz|Z)$/ ? "gzip -dc < $_ |" : $_ } readdir
$other_dir;
  print <>;

The low level functions (open, readdir, etc.) should be there if you need (or want) to use them. Those of us who just want to open a file and manipulate it line-by-line, can use the input operator.

IMPLEMENTATION

<LIST>

Angle brackets are the standard Perl input operators.

Each item in LIST is opened in a DWIM fashion. Dir- and filehandles are left alone. Scalars that contain filenames (if (-f)) are opened as filehandles. Scalars that contain dirnames (if (-d)) are opened as dirhandles. Other scalars ('-', 'some_cmd |', etc.) are opened as filehandles. If any open fails, a warning is issued (or should it die?). The opened handle should be tightly bound to the scalar (or even replace the scalar if stringified filehandles return the string passed to open).

In list context, each item in LIST is opened and read in DWIM fashion. Files are read a line at a time. Directories are read a file at a time.

In scalar context, the next line (or file) is read from the first item in LIST. When the first item returns undef, the next item is read. When there are no more items left, undef is returned.

Inside a while loop (or the conditional section of a for(;;) loop), $_ is assigned to the next line (or file) and tested for defined-ness.

REFERENCES

  RFC 34 - Angle brackets should not be used for file globbing.
  perlop/"I/O Operators"

CHANGES