This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #3763] code example error in "perlopentut"
[perl5.git] / pod / perlopentut.pod
index d3d9f5a..5389c1f 100644 (file)
@@ -5,7 +5,9 @@ perlopentut - tutorial on opening things in Perl
 =head1 DESCRIPTION
 
 Perl has two simple, built-in ways to open files: the shell way for
-convenience, and the C way for precision.  The choice is yours.
+convenience, and the C way for precision.  The shell way also has 2- and
+3-argument forms, which have different semantics for handling the filename.
+The choice is yours.
 
 =head1 Open E<agrave> la shell
 
@@ -36,7 +38,7 @@ virtually the same syntax as the shell.
 The C<open> function takes two arguments: the first is a filehandle,
 and the second is a single string comprising both what to open and how
 to open it.  C<open> returns true when it works, and when it fails,
-returns a false value and sets the special variable $! to reflect
+returns a false value and sets the special variable C<$!> to reflect
 the system error.  If the filehandle was previously opened, it will
 be implicitly closed first.
 
@@ -56,6 +58,14 @@ If you prefer the low-punctuation version, you could write that this way:
 A few things to notice.  First, the leading less-than is optional.
 If omitted, Perl assumes that you want to open the file for reading.
 
+Note also that the first example uses the C<||> logical operator, and the
+second uses C<or>, which has lower precedence.  Using C<||> in the latter
+examples would effectively mean
+
+    open INFO, ( "<  datafile"  || die "can't open datafile: $!" );
+
+which is definitely not what you want.
+
 The other important thing to notice is that, just as in the shell,
 any white space before or after the filename is ignored.  This is good,
 because you wouldn't want these to do different things:
@@ -64,8 +74,8 @@ because you wouldn't want these to do different things:
     open INFO,   "< datafile" 
     open INFO,   "<  datafile"
 
-Ignoring surround whitespace also helps for when you read a filename in
-from a different file, and forget to trim it before opening:
+Ignoring surrounding whitespace also helps for when you read a filename
+in from a different file, and forget to trim it before opening:
 
     $filename = <INFO>;         # oops, \n still there
     open(EXTRA, "< $filename") || die "can't open $filename: $!";
@@ -73,8 +83,46 @@ from a different file, and forget to trim it before opening:
 This is not a bug, but a feature.  Because C<open> mimics the shell in
 its style of using redirection arrows to specify how to open the file, it
 also does so with respect to extra white space around the filename itself
-as well.  For accessing files with naughty names, see L<"Dispelling
-the Dweomer">.
+as well.  For accessing files with naughty names, see 
+L<"Dispelling the Dweomer">.
+
+There is also a 3-argument version of C<open>, which lets you put the
+special redirection characters into their own argument:
+
+    open( INFO, ">", $datafile ) || die "Can't create $datafile: $!";
+
+In this case, the filename to open is the actual string in C<$datafile>,
+so you don't have to worry about C<$datafile> containing characters
+that might influence the open mode, or whitespace at the beginning of
+the filename that would be absorbed in the 2-argument version.  Also,
+any reduction of unnecessary string interpolation is a good thing.
+
+=head2 Indirect Filehandles
+
+C<open>'s first argument can be a reference to a filehandle.  As of
+perl 5.6.0, if the argument is uninitialized, Perl will automatically
+create a filehandle and put a reference to it in the first argument,
+like so:
+
+    open( my $in, $infile )   or die "Couldn't read $infile: $!";
+    while ( <$in> ) {
+       # do something with $_
+    }
+    close $in;
+
+Indirect filehandles make namespace management easier.  Since filehandles
+are global to the current package, two subroutines trying to open
+C<INFILE> will clash.  With two functions opening indirect filehandles
+like C<my $infile>, there's no clash and no need to worry about future
+conflicts.
+
+Another convenient behavior is that an indirect filehandle automatically
+closes when it goes out of scope or when you undefine it:
+
+    sub firstline {
+       open( my $in, shift ) && return scalar <$in>;
+       # no close() required
+    }
 
 =head2 Pipe Opens
 
@@ -85,11 +133,11 @@ character.  That's also the case for Perl.  The C<open> call
 remains the same--just its argument differs.  
 
 If the leading character is a pipe symbol, C<open> starts up a new
-command and open a write-only filehandle leading into that command.
+command and opens a write-only filehandle leading into that command.
 This lets you write into that handle and have what you write show up on
 that command's standard input.  For example:
 
-    open(PRINTER, "| lpr -Plp1")    || die "cannot fork: $!";
+    open(PRINTER, "| lpr -Plp1")    || die "can't run lpr: $!";
     print PRINTER "stuff\n";
     close(PRINTER)                  || die "can't close lpr: $!";
 
@@ -98,22 +146,24 @@ read-only filehandle leading out of that command.  This lets whatever that
 command writes to its standard output show up on your handle for reading.
 For example:
 
-    open(NET, "netstat -i -n |")    || die "cannot fork: $!";
+    open(NET, "netstat -i -n |")    || die "can't fork netstat: $!";
     while (<NET>) { }               # do something with input
     close(NET)                      || die "can't close netstat: $!";
 
-What happens if you try to open a pipe to or from a non-existent command?
-In most systems, such an C<open> will not return an error. That's
-because in the traditional C<fork>/C<exec> model, running the other
-program happens only in the forked child process, which means that
-the failed C<exec> can't be reflected in the return value of C<open>.
-Only a failed C<fork> shows up there.  See L<perlfaq8/"Why doesn't open()
-return an error when a pipe open fails?"> to see how to cope with this.
-There's also an explanation in L<perlipc>.
+What happens if you try to open a pipe to or from a non-existent
+command?  If possible, Perl will detect the failure and set C<$!> as
+usual.  But if the command contains special shell characters, such as
+C<E<gt>> or C<*>, called 'metacharacters', Perl does not execute the
+command directly.  Instead, Perl runs the shell, which then tries to
+run the command.  This means that it's the shell that gets the error
+indication.  In such a case, the C<open> call will only indicate
+failure if Perl can't even run the shell.  See L<perlfaq8/"How can I
+capture STDERR from an external command?"> to see how to cope with
+this.  There's also an explanation in L<perlipc>.
 
 If you would like to open a bidirectional pipe, the IPC::Open2
-library will handle this for you.  Check out L<perlipc/"Bidirectional
-Communication with Another Process">
+library will handle this for you.  Check out 
+L<perlipc/"Bidirectional Communication with Another Process">
 
 =head2 The Minus File
 
@@ -126,8 +176,8 @@ access the standard output.
 If minus can be used as the default input or default output, what happens
 if you open a pipe into or out of minus?  What's the default command it
 would run?  The same script as you're currently running!  This is actually
-a stealth C<fork> hidden inside an C<open> call.  See L<perlipc/"Safe Pipe
-Opens"> for details.
+a stealth C<fork> hidden inside an C<open> call.  See 
+L<perlipc/"Safe Pipe Opens"> for details.
 
 =head2 Mixing Reads and Writes
 
@@ -162,7 +212,7 @@ a binary file as in the WTMP case above, you probably don't want to
 use this approach for updating.  Instead, Perl's B<-i> flag comes to
 the rescue.  The following command takes all the C, C++, or yacc source
 or header files and changes all their foo's to bar's, leaving
-the old version in the original file name with a ".orig" tacked
+the old version in the original filename with a ".orig" tacked
 on the end:
 
     $ perl -i.orig -pe 's/\bfoo\b/bar/g' *.[Cchy]
@@ -175,7 +225,7 @@ L<perlfaq5> for more details.
 
 One of the most common uses for C<open> is one you never
 even notice.  When you process the ARGV filehandle using
-C<E<lt>ARGVE<gt>>, Perl actually does an implicit open 
+C<< <ARGV> >>, Perl actually does an implicit open 
 on each file in @ARGV.  Thus a program called like this:
 
     $ myprogram file1 file2 file3
@@ -189,13 +239,13 @@ using a construct no more complex than:
 
 If @ARGV is empty when the loop first begins, Perl pretends you've opened
 up minus, that is, the standard input.  In fact, $ARGV, the currently
-open file during C<E<lt>ARGVE<gt>> processing, is even set to "-"
+open file during C<< <ARGV> >> processing, is even set to "-"
 in these circumstances.
 
 You are welcome to pre-process your @ARGV before starting the loop to
 make sure it's to your liking.  One reason to do this might be to remove
 command options beginning with a minus.  While you can always roll the
-simple ones by hand, the Getopts modules are good for this.
+simple ones by hand, the Getopts modules are good for this:
 
     use Getopt::Std;
 
@@ -239,7 +289,7 @@ Here's an example:
                 or die "can't open $pwdinfo: $!";
 
 This sort of thing also comes into play in filter processing.  Because
-C<E<lt>ARGVE<gt>> processing employs the normal, shell-style Perl C<open>,
+C<< <ARGV> >> processing employs the normal, shell-style Perl C<open>,
 it respects all the special things we've already seen:
 
     $ myprogram f1 "cmd1|" - f2 "cmd2|" f3 < tmpfile
@@ -248,10 +298,10 @@ That program will read from the file F<f1>, the process F<cmd1>, standard
 input (F<tmpfile> in this case), the F<f2> file, the F<cmd2> command,
 and finally the F<f3> file.
 
-Yes, this also means that if you have a file named "-" (and so on) in
-your directory, that they won't be processed as literal files by C<open>.
-You'll need to pass them as "./-" much as you would for the I<rm> program.
-Or you could use C<sysopen> as described below.
+Yes, this also means that if you have files named "-" (and so on) in
+your directory, they won't be processed as literal files by C<open>.
+You'll need to pass them as "./-", much as you would for the I<rm> program,
+or you could use C<sysopen> as described below.
 
 One of the more interesting applications is to change files of a certain
 name into pipes.  For example, to autoprocess gzipped or compressed
@@ -264,14 +314,14 @@ you can fetch URLs before processing them:
 
     @ARGV = map { m#^\w+://# ? "GET $_ |" : $_ } @ARGV;
 
-It's not for nothing that this is called magic C<E<lt>ARGVE<gt>>.
+It's not for nothing that this is called magic C<< <ARGV> >>.
 Pretty nifty, eh?
 
 =head1 Open E<agrave> la C
 
 If you want the convenience of the shell, then Perl's C<open> is
 definitely the way to go.  On the other hand, if you want finer precision
-than C's simplistic fopen(3S) provides, then you should look to Perl's
+than C's simplistic fopen(3S) provides you should look to Perl's
 C<sysopen>, which is a direct hook into the open(2) system call.
 That does mean it's a bit more involved, but that's the price of 
 precision.
@@ -308,14 +358,14 @@ systems include C<O_BINARY>, C<O_TEXT>, C<O_SHLOCK>, C<O_EXLOCK>,
 C<O_DEFER>, C<O_SYNC>, C<O_ASYNC>, C<O_DSYNC>, C<O_RSYNC>,
 C<O_NOCTTY>, C<O_NDELAY> and C<O_LARGEFILE>.  Consult your open(2)
 manpage or its local equivalent for details.  (Note: starting from
-Perl release 5.6 the O_LARGEFILE flag, if available, is automatically
-added to the sysopen() flags because large files are the the default.)
+Perl release 5.6 the C<O_LARGEFILE> flag, if available, is automatically
+added to the sysopen() flags because large files are the default.)
 
 Here's how to use C<sysopen> to emulate the simple C<open> calls we had
 before.  We'll omit the C<|| die $!> checks for clarity, but make sure
 you always check the return values in real code.  These aren't quite
 the same, since C<open> will trim leading and trailing white space,
-but you'll get the idea:
+but you'll get the idea.
 
 To open a file for reading:
 
@@ -339,7 +389,7 @@ To open a file for update, where the file must already exist:
     sysopen(FH, $path, O_RDWR);
 
 And here are things you can do with C<sysopen> that you cannot do with
-a regular C<open>.  As you see, it's just a matter of controlling the
+a regular C<open>.  As you'll see, it's just a matter of controlling the
 flags in the third argument.
 
 To open a file for writing, creating a new file which must not previously
@@ -377,7 +427,7 @@ in the created files' permissions field.
 For example, if your C<umask> were 027, then the 020 part would
 disable the group from writing, and the 007 part would disable others
 from reading, writing, or executing.  Under these conditions, passing
-C<sysopen> 0666 would create a file with mode 0640, since C<0666 &027>
+C<sysopen> 0666 would create a file with mode 0640, since C<0666 & ~027>
 is 0640.
 
 You should seldom use the MASK argument to C<sysopen()>.  That takes
@@ -393,7 +443,7 @@ folders, cookie files, and internal temporary files.
 Sometimes you already have a filehandle open, and want to make another
 handle that's a duplicate of the first one.  In the shell, we place an
 ampersand in front of a file descriptor number when doing redirections.
-For example, C<2E<gt>&1> makes descriptor 2 (that's STDERR in Perl)
+For example, C<< 2>&1 >> makes descriptor 2 (that's STDERR in Perl)
 be redirected into descriptor 1 (which is usually Perl's STDOUT).
 The same is essentially true in Perl: a filename that begins with an
 ampersand is treated instead as a file descriptor if a number, or as a
@@ -444,8 +494,8 @@ these days.  Here's an example of that:
     $fd = $ENV{"MHCONTEXTFD"};
     open(MHCONTEXT, "<&=$fd")   or die "couldn't fdopen $fd: $!";
 
-If you're using magic C<E<lt>ARGVE<gt>>, you could even pass in as a
-command line argument in @ARGV something like C<"E<lt>&=$MHCONTEXTFD">,
+If you're using magic C<< <ARGV> >>, you could even pass in as a
+command line argument in @ARGV something like C<"<&=$MHCONTEXTFD">,
 but we've never seen anyone actually do this.
 
 =head2 Dispelling the Dweomer
@@ -461,7 +511,7 @@ to C<sysopen>.  To open a file with arbitrary weird characters in
 it, it's necessary to protect any leading and trailing whitespace.
 Leading whitespace is protected by inserting a C<"./"> in front of a
 filename that starts with whitespace.  Trailing whitespace is protected
-by appending an ASCII NUL byte (C<"\0">) at the end off the string.
+by appending an ASCII NUL byte (C<"\0">) at the end of the string.
 
     $file =~ s#^(\s)#./$1#;
     open(FH, "< $file\0")   || die "can't open $file: $!";
@@ -474,7 +524,7 @@ The only vaguely popular system that doesn't work this way is the
 proprietary Macintosh system, which uses a colon where the rest of us
 use a slash.  Maybe C<sysopen> isn't such a bad idea after all.
 
-If you want to use C<E<lt>ARGVE<gt>> processing in a totally boring
+If you want to use C<< <ARGV> >> processing in a totally boring
 and non-magical way, you could do this first:
 
     #   "Sam sat on the ground and put his head in his hands.  
@@ -499,9 +549,9 @@ produce messages like:
     Some warning at scriptname line 29, <FH> line 7.
 
 That's because you opened a filehandle FH, and had read in seven records
-from it.  But what was the name of the file, not the handle?
+from it.  But what was the name of the file, rather than the handle?
 
-If you aren't running with C<strict refs>, or if you've turn them off
+If you aren't running with C<strict refs>, or if you've turned them off
 temporarily, then all you have to do is this:
 
     open($path, "< $path") || die "can't open $path: $!";
@@ -552,7 +602,7 @@ welcome to reopen them if you'd like.
     open(STDOUT, "> output")
        || die "can't open output: $!";
 
-And then these can be read directly or passed on to subprocesses.
+And then these can be accessed directly or passed on to subprocesses.
 This makes it look as though the program were initially invoked
 with those redirections from the command line.
 
@@ -575,11 +625,11 @@ just in a different process:
 
     sub head {
         my $lines = shift || 20;
-        return unless $pid = open(STDOUT, "|-");
+        return if $pid = open(STDOUT, "|-");       # return if parent
         die "cannot fork: $!" unless defined $pid;
         while (<STDIN>) {
-            print;
             last if --$lines < 0;
+            print;
         } 
         exit;
     } 
@@ -606,7 +656,7 @@ What other kinds of files are there than, well, files?  Directories,
 symbolic links, named pipes, Unix-domain sockets, and block and character
 devices.  Those are all files, too--just not I<plain> files.  This isn't
 the same issue as being a text file. Not all text files are plain files.
-Not all plain files are textfiles.  That's why there are separate C<-f>
+Not all plain files are text files.  That's why there are separate C<-f>
 and C<-T> file tests.
 
 To open a directory, you should use the C<opendir> function, then
@@ -620,8 +670,8 @@ name if necessary:
     closedir(DIR);
 
 If you want to process directories recursively, it's better to use the
-File::Find module.  For example, this prints out all files recursively,
-add adds a slash to their names if the file is a directory.
+File::Find module.  For example, this prints out all files recursively
+and adds a slash to their names if the file is a directory.
 
     @ARGV = qw(.) unless @ARGV;
     use File::Find;
@@ -643,13 +693,15 @@ C<readlink> is called for:
         } 
     } 
 
+=head2 Opening Named Pipes
+
 Named pipes are a different matter.  You pretend they're regular files,
 but their opens will normally block until there is both a reader and
 a writer.  You can read more about them in L<perlipc/"Named Pipes">.
 Unix-domain sockets are rather different beasts as well; they're
 described in L<perlipc/"Unix-Domain TCP Clients and Servers">.
 
-When it comes to opening devices, it can be easy and it can tricky.
+When it comes to opening devices, it can be easy and it can be tricky.
 We'll assume that if you're opening up a block device, you know what
 you're doing.  The character devices are more interesting.  These are
 typically used for modems, mice, and some kinds of printers.  This is
@@ -667,8 +719,8 @@ It's often enough to open them carefully:
     print TTYOUT "+++at\015";
     $answer = <TTYIN>;
 
-With descriptors that you haven't opened using C<sysopen>, such as a
-socket, you can set them to be non-blocking using C<fcntl>:
+With descriptors that you haven't opened using C<sysopen>, such as
+sockets, you can set them to be non-blocking using C<fcntl>:
 
     use Fcntl;
     fcntl(Connection, F_SETFL, O_NONBLOCK) 
@@ -683,10 +735,12 @@ and then L<POSIX>, which describes Perl's interface to POSIX.  There are
 also some high-level modules on CPAN that can help you with these games.
 Check out Term::ReadKey and Term::ReadLine.
 
+=head2 Opening Sockets
+
 What else can you open?  To open a connection using sockets, you won't use
-one of Perl's two open functions.  See L<perlipc/"Sockets: Client/Server
-Communication"> for that.  Here's an example.  Once you have it,
-you can use FH as a bidirectional filehandle.
+one of Perl's two open functions.  See 
+L<perlipc/"Sockets: Client/Server Communication"> for that.  Here's an 
+example.  Once you have it, you can use FH as a bidirectional filehandle.
 
     use IO::Socket;
     local *FH = IO::Socket::INET->new("www.perl.com:80");
@@ -718,13 +772,13 @@ handles before doing regular I/O on them:
 
 Passing C<sysopen> a non-standard flag option will also open the file in
 binary mode on those systems that support it.  This is the equivalent of
-opening the file normally, then calling C<binmode>ing on the handle.
+opening the file normally, then calling C<binmode> on the handle.
 
     sysopen(BINDAT, "records.data", O_RDWR | O_BINARY)
         || die "can't open records.data: $!";
 
 Now you can use C<read> and C<print> on that handle without worrying
-about the system non-standard I/O library breaking your data.  It's not
+about the non-standard system I/O library breaking your data.  It's not
 a pretty picture, but then, legacy systems seldom are.  CP/M will be
 with us until the end of days, and after.
 
@@ -738,23 +792,25 @@ sneaky data mutilation behind your back.
 
 Depending on the vicissitudes of your runtime system, even these calls
 may need C<binmode> or C<O_BINARY> first.  Systems known to be free of
-such difficulties include Unix, the Mac OS, Plan9, and Inferno.
+such difficulties include Unix, the Mac OS, Plan 9, and Inferno.
 
 =head2 File Locking
 
 In a multitasking environment, you may need to be careful not to collide
-with other processes who want to do I/O on the same files as others
+with other processes who want to do I/O on the same files as you
 are working on.  You'll often need shared or exclusive locks
 on files for reading and writing respectively.  You might just
 pretend that only exclusive locks exist.
 
 Never use the existence of a file C<-e $file> as a locking indication,
 because there is a race condition between the test for the existence of
-the file and its creation.  Atomicity is critical.
+the file and its creation.  It's possible for another process to create
+a file in the slice of time between your existence check and your attempt
+to create the file.  Atomicity is critical.
 
 Perl's most portable locking interface is via the C<flock> function,
-whose simplicity is emulated on systems that don't directly support it,
-such as SysV or WindowsNT.  The underlying semantics may affect how
+whose simplicity is emulated on systems that don't directly support it
+such as SysV or Windows.  The underlying semantics may affect how
 it all works, so you should learn how C<flock> is implemented on your
 system's port of Perl.
 
@@ -765,7 +821,7 @@ uses locking and another doesn't, all bets are off.
 
 By default, the C<flock> call will block until a lock is granted.
 A request for a shared lock will be granted as soon as there is no
-exclusive locker.  A request for a exclusive lock will be granted as
+exclusive locker.  A request for an exclusive lock will be granted as
 soon as there is no locker of any kind.  Locks are on file descriptors,
 not file names.  You can't lock a file until you open it, and you can't
 hold on to a lock once the file has been closed.
@@ -836,22 +892,54 @@ how to increment a number in a file safely:
     close(FH)
         or die "can't close numfile: $!";
 
+=head2 IO Layers
+
+In Perl 5.8.0 a new I/O framework called "PerlIO" was introduced.
+This is a new "plumbing" for all the I/O happening in Perl; for the
+most part everything will work just as it did, but PerlIO also brought
+in some new features such as the ability to think of I/O as "layers".
+One I/O layer may in addition to just moving the data also do
+transformations on the data.  Such transformations may include
+compression and decompression, encryption and decryption, and transforming
+between various character encodings.
+
+Full discussion about the features of PerlIO is out of scope for this
+tutorial, but here is how to recognize the layers being used:
+
+=over 4
+
+=item *
+
+The three-(or more)-argument form of C<open> is being used and the
+second argument contains something else in addition to the usual
+C<< '<' >>, C<< '>' >>, C<< '>>' >>, C<< '|' >> and their variants,
+for example:
+
+    open(my $fh, "<:utf8", $fn);
+
+=item *
+
+The two-argument form of C<binmode> is being used, for example
+
+    binmode($fh, ":encoding(utf16)");
+
+=back
+
+For more detailed discussion about PerlIO see L<PerlIO>;
+for more detailed discussion about Unicode and I/O see L<perluniintro>.
+
 =head1 SEE ALSO 
 
-The C<open> and C<sysopen> function in perlfunc(1);
-the standard open(2), dup(2), fopen(3), and fdopen(3) manpages;
+The C<open> and C<sysopen> functions in perlfunc(1);
+the system open(2), dup(2), fopen(3), and fdopen(3) manpages;
 the POSIX documentation.
 
 =head1 AUTHOR and COPYRIGHT
 
 Copyright 1998 Tom Christiansen.  
 
-When included as part of the Standard Version of Perl, or as part of
-its complete documentation whether printed or otherwise, this work may
-be distributed only under the terms of Perl's Artistic License.  Any
-distribution of this file or derivatives thereof outside of that
-package require that special arrangements be made with copyright
-holder.
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
 
 Irrespective of its distribution, all code examples in these files are
 hereby placed into the public domain.  You are permitted and