This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Replace default filehandle/select with $DEFOUT, $DEFERR, $DEFIN =head1 VERSION Maintainer: Nathan Wiger <[EMAIL PROTECTED]> Date: 17 Aug 2000 Version: 1 Mailing List: [EMAIL PROTECTED] Number: 129 Status: Developing =head1 ABSTRACT The concept of a "default filehandle" is nebulous. Many users can't get their heads around it, and even if they can, it is still kind of mysterious. This proposes that the "default filehandle" and 2-arg select be dropped from Perl 6 and replaced with the variable C<$DEFOUT>, the Default Output handle. Whatever this variable contains will be what is printed to by default. This will make default output be consistent with the C<fileobject> approach and also other Perl vars. In addition, this RFC proposes two new variables, C<$DEFERR> and C<$DEFIN>, the Default Error and Default Input handles. These can be used to redirect default error output and default input, for added flexibility. =head1 DESCRIPTION =head2 $DEFOUT Currently, the "default filehandle" ("DF" to save typing) is hidden. It can only be accessed or changed via the C<select> function. With the advent of full-featured C<fileobjects>, having a special DF is unnecessary. Instead, we simply make a variable, called C<$DEFOUT>, which is where unspecified output is sent. Below are some examples of Perl 5 versus Perl 6 syntax: P5 P6 ----------------------- ----------------------- select FILE; $DEFOUT = $fileobject; $oldh = select; $oldh = $DEFOUT; $oldh = select FILE; $oldh = $DEFOUT; $DEFOUT = $fileobject; $| = 1 $DEFOUT->autoflush(1); What advantages besides a new syntax are there? Several: 1. The rule is easier. No DF, just "everything goes to $DEFOUT by default". Changing this is done by simple assignment. 2. It's less hidden. Most everything else in Perl is handled in variables such as @INC, %ENV, and so forth. This makes filehandles that much easier. 3. Access to object methods is available directly on the current filehandle object via $DEFOUT->method, eliminating the need for $|, $/, $\, and so on.[1] 4. No more 2-arg select vs. 4-arg select confusion. Whatever object C<$DEFOUT> contains is what default output goes to and what the object methods work on. There is no mysterious hidden DF. C<$DEFOUT> works just like other variables. =head2 $DEFERR The new C<$DEFERR> variable can be used to easily redirect error output as well, something you often want to do if you're not attached to a tty. However, having a script that runs easily in both environments is tricky in Perl 5: if ( $have_a_tty ) { print STDERR "Warning: Bad stuff\n"; } else { print ERRORLOG "Warning: Bad stuff\n"; } You have to put checks similar to this for many functions and different situations. Plus, it doesn't catch C<carp> or C<die> calls embedded in modules, meaning that you will always lose some important error output. With C<$DEFERR>, all error functions are set to act on it instead of C<$STDERR> by default. So, the Perl 6 version of the above is replaced by a single, simple line of code at the top of your main program: $DEFERR = $ERRORLOG unless $have_a_tty; Presto, all error-related functions now redirect to your error log automatically. All through simple assignment. Plus, if you have functions that you want to explicitly print to C<$STDERR> you can still do so, another benefit: warn "Badness!"; # goes to $DEFERR print $STDERR "Badness!" # explicitly to $STDERR This is not possible in Perl 5.[2] =head2 $DEFIN The new C<$DEFIN> accomplishes a similar thing, but with input. Currently, the special <> filehandle acts on one of two things, either C<@ARGV> or <STDIN> (if C<@ARGV> is empty). With C<$DEFIN>, the sequence is instead C<@ARGV> or C<$DEFIN>. This adds valuable functionality: # Figure out our input source based on what's open $DEFIN = $infile || $instream || $STDIN; @data = <>; This allows valuable compartmentalization of code. The simple <> construct is now a synonym for C<$DEFIN>. This means that you can place something like the C<@data = <>> line in a module, and allow the top-level code to change the data source based on a simple assignment. You no longer have to pass filehandles into functions or do complex C<tie> manuevers to gain this ability. Plus, with C<$DEFIN>, if you have a routine that must read from C<$STDIN>, you can still do so easily by explicitly saying: $yes_or_no = <$STDIN>; # explicitly from $STDIN @data = <>; # read from $DEFIN =head2 Naming The naming of the variables was chosen to make them consistent with the Standard IO handles C<$STDIN>, C<$STDOUT>, and C<$STDERR>. =head1 IMPLEMENTATION Remove 2-arg C<select>. Make sure p52p6 translates C<select> to the new syntax. Create C<$DEFOUT> variable and reset output functions to act on C<$DEFOUT> instead of the default filehandle. Add C<$DEFERR> variable and reset error functions (such as warn and die) to print to C<$DEFERR> instead of C<$STDERR>. Add C<$DEFIN> and reset <> and other default input to work on C<$DEFIN> instead of C<$STDIN>. =head1 NOTES [1] This RFC does not take a firm stance on eliminating $|, $/, $\, and friends. However, this approach to handling default input and output does mean they are no longer needed. I do think they should go, but this RFC does not require it. [2] Disclaimer: To my knowledge. But I'm pretty sure. =head1 REFERENCES RFC 14: Modify open() to support FileObjects and Extensibility RFC 30: STDIN, STDOUT, and STDERR should be renamed
