Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Print output of subroutines captured in backticks?

107 views
Skip to first unread message

Mr. Nice Guy

unread,
Oct 20, 2009, 9:58:04 PM10/20/09
to
Hi,

In ksh, I can do something like this:

blat()
{
print "blat says foo"
return 0
}
junk=`blat`
rv=$?

In which case, "$junk" holds "blat says foo", while "$rv" holds 0, or
whatever blat() actually returns. This is really useful in capturing
an error message from the function, as well as the actual return code.

How would I do this in Perl, where I capture the print() statements of
the sub in a variable, but the return value separately? Something
along the lines of:

sub blat ()
{
print "blat says foo";
return 0;
}

my( $junk, $rv );

$junk = `blat`; # -- this doesn't actually work, since blat() isn't
an external executable
$rv = $?;

What I want is whatever blat() might have output via print()
statements into $junk rather than STDOUT, but the return value of the
function in a separate variable; $rv in this case.

I know I can use something like:

sub blat ()
{
print "This will be sent to STDOUT\n";
die( "This will get caught by the eval{ ... }" );
}

eval { blat() };
print $@ if $@;

But this is different.

A. i'm limited to whatever I provide in die(), rather than any or all
output from the function. Don't get me wrong: "eval { ... }" is
useful, and I do use this.

B. die()'s return value is going to be 1 in most, if not all, cases,
not whatever I want to return. Unless there's a way to return a
different value; setting $! didn't seem to work.

Andrzej Adam Filip

unread,
Oct 22, 2009, 5:26:53 PM10/22/09
to

Use "select" to redirect output of "print without specific file-handle"
to string (IO::String);

use IO::String;
my ($returnCode, $output);
my $io = IO::String->new($output);
my $oldfh = select($io);
eval { $returnCode = &blat() };
select($oldfh);

print "returnValue=$returnCode\n";
print "output=\n",$output,"\n";

--
[pl>en Andrew] Andrzej Adam Filip : an...@onet.eu : Andrze...@gmail.com
It is far more impressive when others discover your good qualities without
your help.
-- Miss Manners

Keith Thompson

unread,
Oct 23, 2009, 9:21:35 PM10/23/09
to
Andrzej Adam Filip <andrze...@gmail.com> writes:
[...]

> Use "select" to redirect output of "print without specific file-handle"
> to string (IO::String);
>
> use IO::String;
> my ($returnCode, $output);
> my $io = IO::String->new($output);
> my $oldfh = select($io);
> eval { $returnCode = &blat() };
> select($oldfh);
>
> print "returnValue=$returnCode\n";
> print "output=\n",$output,"\n";

If you have Perl 5.8 or better, you don't need IO::String. Quoting
the IO::String documentation:

Note that perl-5.8 and better has built-in support for "in memory"
files, which are set up by passing a reference instead of a filename to
the open() call. The reason for using this module is that it makes the
code backwards compatible with older versions of Perl.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

0 new messages