Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

The 3 argument file open is "open HANDLE DIRECTION FILENAME". I wanted to have a "generic" open that supports both STDOUT as well as user-defined file names. I could not figure out a way to assign the pre-defined file handles STDOUT (& STDIN) to a filename that would work with the 3 argument file open.

here is the best that i could do :

my ($file,$wFH); if ( @ARGV ) { $file = shift; } else { $file = "STDOUT"; } my $message = "this is a test\n"; if ( $file ne "STDOUT" ) { open $wFH, ">", $file or die; } else { $wFH = *STDOUT; } print $wFH $message;

i was hoping to eliminate the IF block for opening a file. since this allows me to write to either STDOUT or a file, i have "generic" write stmts but not a "generic" open.

is there a better way? thanks

Replies are listed 'Best First'.
Re: assign File Handles to Scalar Variables (open >-)
by ikegami (Patriarch) on Jan 18, 2008 at 00:38 UTC

    The 2-arg open understands - to mean STDIN or STDOUT.

    # XXX Unable to handle paths starting with a space or a # file named "-". The workaround is to prepend "./". my $file = @ARGV ? shift(@ARGV) : '-'; open(my $fh, "> $file") or die("Unable to open output file \"$file\": $!\n"); print $fh "this is a test\n";

    Otherwise, you're stuck with an if statements. You could combine the two if statements into one, though.

    Update: Added code.

Re: assign File Handles to Scalar Variables (select)
by ikegami (Patriarch) on Jan 18, 2008 at 00:45 UTC
    I just thought of another way: select.
    if ( @ARGV ) { my $file = shift(@ARGV); open(my $fh, "> $file") or die("Unable to open output file \"$file\": $!\n"); select($fh); } print "this is a test\n";
Re: assign File Handles to Scalar Variables
by starX (Chaplain) on Jan 18, 2008 at 00:41 UTC
    The scalar ref method doesn't work that way, you can't assign a bareword. It should look like this:
    open my $filehandle, '>', $filename or die "$!";
    If you want to open a generic handle, I think you might want to look into IO::Tee. When you invoke it, you can specify an input handle and an output handle, thusly:
    use IO:Tee; open my $input_handle, $in_filename or die "$!"; open my $output_handle, '>', $out_filename or die "$!"; $generic_handle = IO::Tee->new($input_handle, $output_handle);
    That will let you read or write to $generic_handle

    Update: Added code to clarify you have to open $input_handle and $output_handle before teeing them.

    --starX
    axisoftime.com
Re: assign File Handles to Scalar Variables
by BrowserUk (Patriarch) on Jan 18, 2008 at 04:44 UTC