Reputation: 59
for a program i am trying to write in perl right now, i want to build in an option that makes the output go to an output file, which is pretty easy with the perl module Getopt. however, if the option is not used, i would like the output to go to the terminal (STDOUT). for that i wrote a little script to test if i could build a switch with the module IO::File.
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;
use IO::File;
my $outfilename;
GetOptions (
"out=s" => \$outfilename,
);
my $out = IO::File->new(">$outfilename");
if (defined $out) {
print $out "Hello World!\n";
}
else {
print "Hello World!\n";
}
close $out if $outfilename;
although the program "runs" with or without a -o option, when i run it without -o, perl tells me that $outfilename in line 13 is not initialized, which i guess is because Getopt returns variables as "false" when the option is not used. however, i cannot think of a way to circumvent this. can you guys help me out?
also, i am absolutely sure that there is a much easier way to build in such a switch that i am not aware of. i was just writing this because i couldn't find any better way online, so if you guys have any tips on how to do that smarter, i would be very grateful!
Upvotes: 2
Views: 98
Reputation: 385506
You get the warning because you use $outfilename
as a file name unconditionally even though it only has a value when --out
has been provided.
Don't put the entire print
in the if
. You end up with lots of duplicated code if you do that. Either create a file handle that's initialized under all conditions
my $outfh;
if (defined($outfilename)) {
open($outfh, '>', $outfilename)
or die($!);
} else {
$outfh = \*STDOUT;
}
print $outfh "Hello World!\n";
or redirect STDOUT
if (defined($outfilename)) {
open(STDOUT, '>', $outfilename)
or die($!);
}
print "Hello World!\n";
But why aren't you redirecting STDOUT from the outside?
script >script.log
Upvotes: 4
Reputation: 7996
You'd better take a look at the following:
The select
call lets you redefine what is the default file handler for the print
calls.
SelectSaver
lets you do the same thing in the scope of a given block of code.
In your case you could rewrite your code so that you create the output file handle if needed and select
it, before running the code that will do the output. The outputting code, in turn, would just call print
without file handle.
Upvotes: -1
Reputation: 67900
You can use select
to set the default output file handle. This will make print
automatically print to the select
ed file handle.
if ($outfilename) {
open my $outfh, ">", $outfilename
or die "Cannot open $outfilename for output: $!";
select $outfh;
}
print "Hello world!\n";
Upvotes: 4
Reputation: 4445
You can just replace STDOUT with your filehandle, and then print normally.
if($outfilename) {
open my $of, ">", $outfilename;
*STDOUT = $of;
}
print "Hello World!\n";
Upvotes: 0