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