10.10. Power Slurping
Slurp a stream with Perl6::Slurp for power and simplicity.
Reading in an entire input stream is common enough, and the do {...} idiom is ugly enough, that the next major version of Perl (Perl 6) will provide a built-in function to handle it directly. Appropriately, that builtin will be called slurp.
Perl 5 doesn't have an equivalent builtin, and there are no plans to add one, but the future functionality is available in Perl 5 today, via the Perl6::Slurp CPAN module. Instead of:
my $text = do { local $/; <$file_handle> };
you can just write:
use Perl6::Slurp;
my $text = slurp $file_handle;
which is cleaner, clearer, more concise, and consequently less error-prone.
The slurp( ) subroutine is also much more powerful. For example, if you have only the file's name, you would have to write:
my $text = do {
open my $fh, '<', $filename or croak "$filename: $OS_ERROR";
local $/;
<$fh>;
};
which almost seems more trouble than it's worth. Or you can just give slurp( ) the filename directly:
my $text = slurp $filename;
and it will open the file and then read in its full contents for you.
In a list context, slurp( ) acts like a regular <> or readline, reading in every line separately and returning them all in a list:
my @lines = slurp $filename;
The slurp( ) subroutine also has a few useful features that <> and readline lack. For example, you can ask it to automatically chomp each line before it returns:
my @lines = slurp $filename, {chomp => 1};
or, instead of removing the line-endings, it can convert each one to some other character sequence (say, '[EOL]'):
my @lines = slurp $filename, {chomp => '[EOL]'};
or you can change the input record separatorjust for that particular call to slurp( )without having to monkey with the $/ variable:
# Slurp chunks...
my @paragraphs = slurp $filename, {irs => $EMPTY_STR};
Setting the input record separator to an empty string causes <> or slurp to read "paragraphs" instead of lines, where each "paragraph" is a chunk of text ending in two or more newlines.
You can even use a regular expression to specify the input record separator, instead of the plain string that Perl's standard $/ variable restricts you to:
# Read "human" paragraphs (separated by two or more whitespace-only lines)...
my @paragraphs = slurp $filename, {irs => qr/\n \s* \n/xms};
 |