Function that (also) writes to STDOUT or STDERR


There are many cases when we encounter a function that does more than one things. For example in the following simplified example we have a function that both makes some (simple) mathematical calculation and prints to the screen. For added fun it also prints to the Standard Error channel.

We will probably want to refactor it to separate the concerns of calculating and IO, but first we'd like to write a unit-test.

In this example we use the capture function of the Capture::Tiny module that will capture and return as a string everything that is printed to STDOUT and STDERR. (It could also capture the exit value of an external call, but this is not relevant in our case.

The whole code is wrapped in a subtest so the external $result variable will be lexically scoped.


examples/capture-stdout-stderr/lib/CalcOutput.pm
package CalcOutput;
use strict;
use warnings;

use Exporter qw(import);
our @EXPORT_OK = qw(calc_and_print);

sub calc_and_print {
    my ($x, $y) = @_;

    my $z = $x + $y;
    print "The result on STDOUT is $z\n";
    print STDERR "Some messages sent to STDERR\n";

    return $z;
}


1;

examples/capture-stdout-stderr/bin/calc.pl
use strict;
use warnings;

use CalcOutput qw(calc_and_print);

die "Usage: $0 NUM NUM\n" if @ARGV != 2;

my $result = calc_and_print(@ARGV);
print "The result is $result.\n";

perl -Ilib bin/calc.pl 7 8