IO::Cap...Overview(3)
π NAME π
IO::Capture::Extended β Extend functionality of IO::Capture β¨
(yes bestie, we're in the IO::Capture::Extended(3) page from the User Contributed Perl Documentation, and it is giving main character energy π)
β¨ SYNOPSIS β¨
okay so listen. the programmer interface is literally just two classes, no cap π
π
IO::Capture::Stdout::Extended
use IO::Capture::Stdout::Extended;
$capture = IO::Capture::Stdout::Extended->new();
$capture->start();
# some code that prints to STDOUT
$capture->stop();
# scalar context: return number of print statements with 'fox'
$matches = $capture->grep_print_statements('fox');
# list context: return list of print statements with 'fox'
@matches = $capture->grep_print_statements('fox');
# return number of print statements
$matches = $capture->statements;
# scalar context: return number of pattern matches
$regex = qr/some regular expression/;
$matches = $capture->matches($regex);
# list context: return list of pattern matches
@matches = $capture->matches($regex);
# return reference to array holding list of pattern matches
$matchesref = $capture->matches_ref($regex);
# scalar context: return number of 'screen' lines printed
$screen_lines = $capture->all_screen_lines();
# list context: return list of 'screen' lines printed
@all_screen_lines = $capture->all_screen_lines();
π
IO::Capture::Stderr::Extended
$capture = IO::Capture::Stderr::Extended->new();
$capture->start();
# some code that prints to STDERR
$capture->stop();
... and then use all the methods defined above for IO::Capture::Stdout::Extended. periodt π
πΈ DESCRIPTION πΈ
so IO::Capture::Extended is a distribution made up of two whole classes, and each one is a lil collection of subroutines π«Ά They're there to extend the functionality of the CPAN modules IO::Capture::Stdout and IO::Capture::Stderr β and they hit different when you're in a testing context, like the one you get from Test::Simple, Test::More or any other module built on Test::Builder. obsessed, honestly π
π¦ USAGE π¦
π Requirements π
You need the IO::Capture distribution, available from CPAN at http://search.cpan.org/~reynolds/IO-Capture-0.05/ β¨
Use version 0.05 or later, bestie β that's how you take advantage of important bug fixes ππ¨
The IO::Capture distribution includes the base class IO::Capture, IO::Capture::Stdout, IO::Capture::Stderr and other packages. It also includes useful documentation in IO::Capture::Overview. iconic of it, fr fr π
π General Comments π
The IO::Capture::Stdout::Extended and IO::Capture::Stdout::Extended methods (yes, the original literally says Stdout twice β keeping it exactly as written, we don't edit the ancestors π) are designed to hand back return values that work nicely as arguments to Test::More functions like ok(), is() and like(). That's the whole objective and the examples below show it off π
Suggestions are welcome for additional methods which would fulfill that objective β so if you've got ideas, they want them π«Ά
πΈ Individual Methods πΈ
Note: SinceIO::Capture::Extendedis structured so as to make exactly the same methods available forIO::Capture::Stdout::ExtendedandIO::Capture::Stderr::Extended, whenver (their spelling, iykyk π) there appears below a reference to, e.g.,IO::Capture::Stdout::Extended::grep_print_statements(), you should assume that the remarks apply equally toIO::Capture::Stderr::Extended::grep_print_statements(). Wherever reference is made to STDOUT, the remarks apply to STDERR as well.
π
grep_print_statements()
Scalar Context π
Problem: You wish to test a function that prints to STDOUT. You can predict the number of "print" statements that match a pattern and wish to test that prediction. (The example below is adapted from IO::Capture::Overview.)
sub print_fox {
print "The quick brown fox jumped over ...";
print "garden wall";
print "The quick red fox jumped over ...";
print "garden wall";
}
$capture->start;
print_fox();
$capture->stop;
$matches = $capture->grep_print_statements('fox');
is($capture->grep_print_statements('fox'), 2,
"correct no. of print statements grepped");
Solution: Precede the function call with a call to the IO::Capture::Stdout::Extended start() method and follow it with a call to the stop() method. Call grep_print_statements. Use its return value as one of two arguments to Test::More::is(). Use your prediction as the other argument. Add a useful comment to is(). slay π
Potential Pitfall: The number of print statements captured between IO::Capture::Stdout::Extended::start() and stop() is not necessarily the number of lines that would appear to be printed to standard output by a given block of code. If your subroutine or other code block prints partial lines β i.e., lines lacking "\n" newline characters β the number of print statements will be greater than the number of ''screen lines.'' This is illustrated by the following:
sub print_fox_long {
print "The quick brown fox jumped over ...";
print "a less adept fox\n";
print "The quick red fox jumped over ...";
print "the garden wall\n";
}
$capture->start;
print_fox_long();
$capture->stop;
$matches = $capture->grep_print_statements("fox");
is($capture->grep_print_statements("fox"), 3,
"correct no. of print statements grepped");
The number of "print" statements matching "fox" is three β even though the number of lines on the screen which appear on STDOUT containing "fox" is only two. not the vibes you expected, huh π
List Context π
Problem: As above, you wish to test a function that prints to STDOUT. This time, you can predict the content of "print" statements that match a pattern and wish to test that prediction.
%matches = map { $_, 1 } $capture->grep_print_statements('fox');
is(keys %matches, 2, "correct no. of print statements grepped");
ok($matches{'The quick brown fox jumped over ...'},
'print statement correctly grepped');
ok($matches{'The quick red fox jumped over ...'},
'print statement correctly grepped');
Solution: As above, call grep_print_statements, but map its output to a 'seen-hash'. You can then use the number of keys in that seen-hash as an argument to Test::More::is(). You can use ok() to test whether the keys of that hash are as predicted. chef's kiss π§
π
statements()
Problem: You've written a function which prints to STDOUT. You can make a prediction as to the number of screen lines which should be printed. You want to test that prediction with Test::More::is().
sub print_greek {
local $_;
print "$_\n" for (qw| alpha beta gamma delta |);
}
$capture->start();
print_greek();
$capture->stop();
is($capture->statements, 4,
"number of print statements is correct");
Solution: Precede the function call with a call to the IO::Capture::Stdout start() method and follow it with a call to the stop() method. Call IO::Capture::Stdout::Extended::statements() and use its return value as the first argument to is(). Use your prediction as the second argument to is(). Be sure to write a useful comment for your test π«Ά
Potential Pitfall: The number of print statements returned by statements is not necessarily the number of lines that would appear to be printed to standard output by a given block of code. If your subroutine or other code block prints partial lines β i.e., lines lacking "\n" newline characters β the number of print statements will be greater than the number of ''screen lines.'' This is illustrated by the following:
sub print_greek_long {
local $_;
for (qw| alpha beta gamma delta |) {
print $_;
print "\n";
}
}
$capture->start();
print_greek_long();
$capture->stop();
is($capture->statements, 8,
"number of print statements is correct");
This pitfall can be avoided by using all_screen_lines() below. π‘
π
all_screen_lines()
Scalar Context π
Returns the number of lines which would normally be counted by eye on STDOUT. This number is not necessarily equal to the number of print() statements found in the captured output. This method avoids the 'pitfall' found when using statements() above. she's the fixer π
$capture->start();
print_greek_long();
$capture->stop();
$screen_lines = $capture->all_screen_lines;
is($screen_lines, 4, "correct no. of lines printed to screen");
List Context π
Returns an array holding lines as normally viewed on STDOUT. The size of this array is not necessarily equal to the number of print() statements found in the captured output. This method avoids the 'pitfall' found when using statements() above.
$capture->start();
print_greek_long();
$capture->stop();
@all_screen_lines = $capture->all_screen_lines;
is($all_screen_lines[0],
"alpha",
"line correctly printed to screen");
is($all_screen_lines[1],
"beta",
"line correctly printed to screen");
Any newline ("\n") appearing at the end of a screen line is not included in the list of lines returned by this method, i.e., the lines are chomped. yeah they got the chop βοΈβ¨
π
matches()
Scalar Context π
Problem: You've written a function which, much like the ''mail merge'' function in word processing programs, extracts data from some data source, merges the data with text in a standard form, and prints the result to STDOUT. You make a prediction as to the number of forms which are printed to STDOUT and wish to confirm that prediction.
my @week = (
[ qw| Monday Lundi Lunes | ],
[ qw| Tuesday Mardi Martes | ],
[ qw| Wednesday Mercredi Miercoles | ],
[ qw| Thursday Jeudi Jueves | ],
[ qw| Friday Vendredi Viernes | ],
[ qw| Saturday Samedi Sabado | ],
[ qw| Sunday Dimanche Domingo | ],
);
sub print_week {
my $weekref = shift;
my @week = @{$weekref};
for (my $day=0; $day<=$#week; $day++) {
print "English: $week[$day][0]\n";
print "French: $week[$day][1]\n";
print "Spanish: $week[$day][2]\n";
print "\n";
}
}
$capture->start();
print_week(\@week);
$capture->stop();
$regex = qr/English:.*?French:.*?Spanish:/s;
β¦and that's where part 1 of this page stops, bestie π more coming, don't go anywhere π
β¦and yeah, that test wraps up like this π«Ά
is($capture->matches($regex), 7,
"correct number of forms printed to screen");
Solution: slip a call to the IO::Capture::Stdout start() method in before you call the function, then follow it with a call to the stop() method β bookends, bestie β¨. Write a Perl regular expression and assign it to a variable using the qr// notation. (Lowkey important: remember to use the /s modifier if the text you're testing crosses screen lines π.) Pass that regex variable to IO::Capture::Stdout::Extended::matches(), and use whatever that method call returns as one argument to Test::More::is(). Your prediction goes in as the second argument to is(). And fr fr, write a useful comment for your test β future you will be so grateful π
π§Ύ List Context π§Ύ
Problem: As above, you've written a function which, much like the ''mail merge'' function in word processing programs, extracts data from some data source, merges the data with text in a standard form, and prints the result to STDOUT. This time, however, you wish to do a quick test on the results by examining a sample form.
$capture->start();
print_week(\@week); # as defined above
$capture->stop();
@matches = $capture->matches($regex);
$predicted = "English: Monday\nFrench: Lundi\nSpanish:";
is($matches[0], $predicted, "first form matches test portion");
Solution: Same as above, but this time you grab the output of matches() in a list or array. Write a string that predicts the typical contents of one instance of your merged form. Take the contents of one form (that's one element in the list output) plus your prediction string and pass them as arguments to is(). Be sure to write a useful comment for your test π
Problem: As above, but now you wish to make sure that a form was generated for each required field in the data source.
$regex = qr/French:\s+(.*?)\n/s;
@predicted = qw| Lundi Mardi Mercredi Jeudi
Vendredi Samedi Dimanche |;
ok(eq_array( [ $capture->matches($regex) ], \@predicted ),
"all predicted matches found");
Solution: Similar to above, but now you predict which data points are going to show up in the output, and you store that prediction in a list or array. Take references to (a) the array holding that prediction, and (b) the result of $capture-"matches($regex)> β literally how it's written here, typo and all, keeping it π― faithful π. Hand those two references to Test::More's utility function eq_array, which returns a true value if the underlying arrays are identical element-by-element. Then pass that value to ok(). As always, bestie: write a useful comment for your test β¨
π matches_ref() π
Problem: Same as the first ''List Context'' example above, but now you would prefer to work with a method that returns an array reference rather than all the elements in a list.
$matchesref = $capture->matches_ref($regex);
is(${$matchesref}[0], $predicted, "first form matches test portion");
Solution: Call IO::Capture::Stdout::Extended::matches_ref() instead of matches. You will have to rephrase your test in terms of an element of a dereferenced array β dereferencing is giving main character energy here, no cap π
π BUGS π
As Paul Johnson says, ''Did I mention that this is alpha code?''.
So likeβ¦ yes. Alpha. You have been warned, bestie π
π«Ά SUPPORT π«Ά
Contact the author or post to the perl-qa mailing list.
π ACKNOWLEDGEMENTS π
Thanks go first and foremost to the two authors of the IO::Capture distribution, Mark Reynolds and Jon Morgan. Mark Reynolds was responsive to this module's author's suggestions for bug fixes and additional tests. The documentation found in IO::Capture::Overview was particularly helpful in showing me how to extend IO::Capture's functionality. This distribution is maintained independently but will be updated as needed if and when IO::Capture is revised.
The methods in IO::Capture::Extended are offered to the Perl community in gratitude for being turned on to IO::Capture by David Cantrell on the perl.qa mailing list in February 2005 (http://www.nntp.perl.org/group/perl.qa/3567) π¦
Other contributors to that discussion thread whose suggestions are reflected in this module were David H. Adler, David Golden, Michael G. Schwern and Tels. Fergal Daly also made suggestions in separate communications.
The structure for this module was created with my own hacked-up version of R. Geoffrey Avery's modulemaker utility, based on his CPAN module ExtUtils::ModuleMaker.
π AUTHOR π
James E Keenan. CPAN ID: JKEENAN. jkeenan [at] pobox [dot] com.
β¨ COPYRIGHT β¨
Copyright 2005-26 James E Keenan.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
πΈ SEE ALSO πΈ
perl(1). IO::Capture; IO::Capture::Stdout; IO::Capture::Overview. Test::Simple; Test::More.
And that's a wrap on part 2, bestie π this whole thing is perl v5.42.3, dated 2026-10-22, living its life as IO::Cap...Overview(3) β go forth and capture that output, periodt π
π¦ where this page comes from
- fedora 43: perl-IO-Capture-Extended 0.14-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- fedora 44: perl-IO-Capture-Extended 0.14-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms