tags:

views:

143

answers:

4

I'm curious if I can toggle between printing to STDOUT or STDERR based on some value or inline expression (without using an if statement).

print ($someFlag ? STDOUT : STDERR) "hello world!"

Obviously, that syntax doesn't work.

+6  A: 

Do you need to evaluate for each call to print?

If not, would this work for you:

my $redir = $someFlag ? STDOUT : STDERR;
print $redir "hello world!\n";
jheddings
I'll take it. I only have one call to print, but 2 lines to do it are fine. Just thought it would be nice inline ...
Keith Bentrup
+4  A: 

One mechanism is to 'select' the output descriptor (file channel).

select STDERR;
print ...goes to STDERR...;
select STDOUT;
print ...goes to STDOUT...;

I suspect this is now deprecated, though.

Jonathan Leffler
no, not deprecated; why would it be?
ysth
@ysth Why would you deprecate it? Because its global side effect that makes the convenient shorthand of "print $string == print STDOUT $string" unreliable. And it overloads the select() function with two totally different meanings.
Schwern
+11  A: 

I think this will do what you want:

print {$someFlag ? *STDOUT : *STDERR} "hello world!";

A similar example can be seen in the documentation for print. Use typeglobs so that it will run under use strict.

Another strategy is to define your own printing function that will behave differently, depending on the value of $someFlag.

FM
+3  A: 

I wrap this sort of thing in a method that returns the appropriate filehandle:

 print { $obj->which_handle_do_I_want } "Some message";

You might want to look at how IO::Interactive.

However, if you're doing this for logging, I recommend Log::Log4perl since you can not only change where the output goes, but can send the output to multiple places, set priorities for the message, and a lot more. And, you can change all of that without changing the source.

brian d foy